Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 920fa0f0e28c0a57d683a2dc3f252bab > files > 3

m2crypto-0.16-9.el5.src.rpm

diff -u m2crypto-0.16/SWIG/_lib.i m2crypto-0.16/SWIG/_lib.i
--- m2crypto-0.16/SWIG/_lib.i	2008-12-04 18:57:47.000000000 +0100
+++ m2crypto-0.16/SWIG/_lib.i	2009-04-06 20:12:58.000000000 +0200
@@ -206,28 +206,35 @@
 
 void gen_callback(int p, int n, void *arg) {
     PyObject *argv, *ret, *cbfunc;
- 
+    PyGILState_STATE gilstate;
+
+    gilstate = PyGILState_Ensure();
     cbfunc = (PyObject *)arg;
     argv = Py_BuildValue("(ii)", p, n);
     ret = PyEval_CallObject(cbfunc, argv);
     Py_DECREF(argv);
     Py_XDECREF(ret);
+    PyGILState_Release(gilstate);
 }
 
 int passphrase_callback(char *buf, int num, int v, void *arg) {
     int i, len;
     char *str;
     PyObject *argv, *ret, *cbfunc;
+    PyGILState_STATE gilstate;
 
+    gilstate = PyGILState_Ensure();
     cbfunc = (PyObject *)arg;
     argv = Py_BuildValue("(i)", v);
     ret = PyEval_CallObject(cbfunc, argv);
     Py_DECREF(argv);
     if (ret == NULL) {
+        PyGILState_Release(gilstate);
         return -1;
     }
     if (!PyString_Check(ret)) {
         Py_DECREF(ret);
+        PyGILState_Release(gilstate);
         return -1;
     }
     if ((len = PyString_Size(ret)) > num)
@@ -236,6 +243,7 @@
     for (i = 0; i < len; i++)
         buf[i] = str[i];
     Py_DECREF(ret);
+    PyGILState_Release(gilstate);
     return len;
 }
 %}
@@ -418,8 +426,10 @@
 /* A bunch of "straight-thru" functions. */
 
 %rename(err_print_errors_fp) ERR_print_errors_fp;
+%threadallow ERR_print_errors_fp;
 extern void ERR_print_errors_fp(FILE *);
 %rename(err_print_errors) ERR_print_errors;
+%threadallow ERR_print_errors;
 extern void ERR_print_errors(BIO *);
 %rename(err_get_error) ERR_get_error;
 extern unsigned long ERR_get_error(void);
diff -u m2crypto-0.16/SWIG/_ssl.i m2crypto-0.16/SWIG/_ssl.i
--- m2crypto-0.16/SWIG/_ssl.i	2008-12-04 19:06:57.000000000 +0100
+++ m2crypto-0.16/SWIG/_ssl.i	2009-04-06 20:12:58.000000000 +0200
@@ -81,6 +81,7 @@
 %rename(ssl_new) SSL_new;
 extern SSL *SSL_new(SSL_CTX *);
 %rename(ssl_free) SSL_free;
+%threadallow SSL_free;
 extern void SSL_free(SSL *);
 %rename(ssl_dup) SSL_dup;
 extern SSL *SSL_dup(SSL *);
@@ -95,12 +96,15 @@
 %rename(ssl_set_shutdown) SSL_set_shutdown;
 extern void SSL_set_shutdown(SSL *, int);
 %rename(ssl_shutdown) SSL_shutdown;
+%threadallow SSL_shutdown;
 extern int SSL_shutdown(SSL *);
 %rename(ssl_clear) SSL_clear;
 extern int SSL_clear(SSL *);
 %rename(ssl_do_handshake) SSL_do_handshake;
+%threadallow SSL_do_handshake;
 extern int SSL_do_handshake(SSL *);
 %rename(ssl_renegotiate) SSL_renegotiate;
+%threadallow SSL_renegotiate;
 extern int SSL_renegotiate(SSL *);
 %rename(ssl_pending) SSL_pending;
 extern int SSL_pending(CONST SSL *);
@@ -139,6 +143,7 @@
 %rename(ssl_session_free) SSL_SESSION_free;
 extern void SSL_SESSION_free(SSL_SESSION *);
 %rename(ssl_session_print) SSL_SESSION_print;
+%threadallow SSL_SESSION_print;
 extern int SSL_SESSION_print(BIO *, CONST SSL_SESSION *);
 %rename(ssl_session_set_timeout) SSL_SESSION_set_timeout;
 extern long SSL_SESSION_set_timeout(SSL_SESSION *, long);
@@ -392,10 +397,9 @@
 
 static int ssl_sleep_with_timeout(SSL *ssl, const struct timeval *start,
                                   double timeout, int ssl_err) {
-    PyGILState_STATE gilstate;
     struct pollfd fd;
     struct timeval tv;
-    int ms;
+    int ms, tmp;
 
     assert(timeout > 0);
  again:
@@ -435,12 +439,13 @@
             assert(0);
     }
     if (fd.fd == -1) {
-        gilstate = PyGILState_Ensure();
         PyErr_SetString(_ssl_err, "timeout on a non-FD SSL");
-        PyGILState_Release(gilstate);
         return -1;
     }
-    switch (poll(&fd, 1, ms)) {
+    Py_BEGIN_ALLOW_THREADS
+    tmp = poll(&fd, 1, ms);
+    Py_END_ALLOW_THREADS
+    switch (tmp) {
     	case 1:
             return 0;
     	case 0:
@@ -448,17 +453,13 @@
     	case -1:
             if (errno == EINTR)
                 goto again;
-            gilstate = PyGILState_Ensure();
             PyErr_SetFromErrno(_ssl_err);
-            PyGILState_Release(gilstate);
             return -1;
     }
     return 0;
 
  timeout:
-    gilstate = PyGILState_Ensure();
     PyErr_SetString(_ssl_timeout_err, "timed out");
-    PyGILState_Release(gilstate);
     return -1;
 }
 
@@ -466,15 +467,14 @@
     PyObject *obj = NULL;
     int r, ssl_err;
     struct timeval tv;
-    PyGILState_STATE gilstate;
 
     if (timeout > 0)
         gettimeofday(&tv, NULL);
  again:
+    Py_BEGIN_ALLOW_THREADS
     r = SSL_accept(ssl);
     ssl_err = SSL_get_error(ssl, r);
-
-    gilstate = PyGILState_Ensure();
+    Py_END_ALLOW_THREADS
 
     switch (ssl_err) {
         case SSL_ERROR_NONE:
@@ -488,10 +488,8 @@
                 break;
             }
 
-            PyGILState_Release(gilstate);
             if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
                 goto again;
-            gilstate = PyGILState_Ensure();
 
             obj = NULL;
             break;
@@ -503,8 +501,6 @@
             break;
     }
 
-    PyGILState_Release(gilstate);
-
     return obj;
 }
 
@@ -512,16 +508,15 @@
     PyObject *obj = NULL;
     int r, ssl_err;
     struct timeval tv;
-    PyGILState_STATE gilstate;
 
     if (timeout > 0)
         gettimeofday(&tv, NULL);
  again:
+    Py_BEGIN_ALLOW_THREADS
     r = SSL_connect(ssl);
     ssl_err = SSL_get_error(ssl, r);
+    Py_END_ALLOW_THREADS
 
-    gilstate = PyGILState_Ensure();
-    
     switch (ssl_err) {
         case SSL_ERROR_NONE:
         case SSL_ERROR_ZERO_RETURN:
@@ -534,10 +529,8 @@
                 break;
             }
 
-            PyGILState_Release(gilstate);
             if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
                 goto again;
-            gilstate = PyGILState_Ensure();
 
             obj = NULL;
             break;
@@ -549,8 +542,6 @@
             break;
     }
     
-    PyGILState_Release(gilstate);
-    
     return obj;
 }
 
@@ -563,24 +554,18 @@
     void *buf;
     int r;
     struct timeval tv;
-    PyGILState_STATE gilstate;
-
-    gilstate = PyGILState_Ensure();
 
     if (!(buf = PyMem_Malloc(num))) {
         PyErr_SetString(PyExc_MemoryError, "ssl_read");
-        PyGILState_Release(gilstate);
         return NULL;
     }
 
-    PyGILState_Release(gilstate);
-
     if (timeout > 0)
         gettimeofday(&tv, NULL);
  again:
+    Py_BEGIN_ALLOW_THREADS
     r = SSL_read(ssl, buf, num);
-
-    gilstate = PyGILState_Ensure();
+    Py_END_ALLOW_THREADS
 
     if (r >= 0) {
         buf = PyMem_Realloc(buf, r);
@@ -603,10 +588,8 @@
                     break;
                 }
 
-                PyGILState_Release(gilstate);
                 if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
                     goto again;
-                gilstate = PyGILState_Ensure();
 
                 obj = NULL;
                 break;
@@ -620,8 +603,6 @@
     }
     PyMem_Free(buf);
 
-    PyGILState_Release(gilstate);
-
     return obj;
 }
 
@@ -629,21 +610,15 @@
     PyObject *obj = NULL;
     void *buf;
     int r, err;
-    PyGILState_STATE gilstate;
-
-    gilstate = PyGILState_Ensure();
 
     if (!(buf = PyMem_Malloc(num))) {
         PyErr_SetString(PyExc_MemoryError, "ssl_read");
-        PyGILState_Release(gilstate);
         return NULL;
     }
     
-    PyGILState_Release(gilstate);
-    
+    Py_BEGIN_ALLOW_THREADS
     r = SSL_read(ssl, buf, num);
-    
-    gilstate = PyGILState_Ensure();
+    Py_END_ALLOW_THREADS
     
     switch (SSL_get_error(ssl, r)) {
         case SSL_ERROR_NONE:
@@ -674,8 +649,6 @@
     }
     PyMem_Free(buf);
     
-    PyGILState_Release(gilstate);
-    
     return obj;
 }
 
@@ -683,24 +656,18 @@
     const void *buf;
     int len, r, ssl_err, ret;
     struct timeval tv;
-    PyGILState_STATE gilstate;
-
-    gilstate = PyGILState_Ensure();
 
     if (PyObject_AsReadBuffer(blob, &buf, &len) == -1) {
-        PyGILState_Release(gilstate);
         return -1;
     }
 
-    PyGILState_Release(gilstate);
-
     if (timeout > 0)
         gettimeofday(&tv, NULL);
  again:
+    Py_BEGIN_ALLOW_THREADS
     r = SSL_write(ssl, buf, len);
     ssl_err = SSL_get_error(ssl, r);
-
-    gilstate = PyGILState_Ensure();
+    Py_END_ALLOW_THREADS
 
     switch (ssl_err) {
         case SSL_ERROR_NONE:
@@ -715,10 +682,8 @@
                 break;
             }
 
-            PyGILState_Release(gilstate);
             if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
                 goto again;
-            gilstate = PyGILState_Ensure();
 
             ret = -1;
             break;
@@ -730,28 +695,20 @@
             ret = -1;
     }
     
-    PyGILState_Release(gilstate);
-    
     return ret;
 }
 
 int ssl_write_nbio(SSL *ssl, PyObject *blob) {
     const void *buf;
     int len, r, err, ret;
-    PyGILState_STATE gilstate;
-
-    gilstate = PyGILState_Ensure();
 
     if (PyObject_AsReadBuffer(blob, &buf, &len) == -1) {
-        PyGILState_Release(gilstate);
         return -1;
     }
 
-    PyGILState_Release(gilstate);
-    
+    Py_BEGIN_ALLOW_THREADS
     r = SSL_write(ssl, buf, len);
-    
-    gilstate = PyGILState_Ensure();
+    Py_END_ALLOW_THREADS
     
     switch (SSL_get_error(ssl, r)) {
         case SSL_ERROR_NONE:
@@ -778,8 +735,6 @@
             ret = -1;
     }
     
-    PyGILState_Release(gilstate);
-    
     return ret;
 }
 
@@ -810,15 +765,24 @@
 X509 *sk_x509_value(STACK *stack, int idx) {
     return (X509 *)sk_value(stack, idx);
 }
+%}
 
+%threadallow i2d_ssl_session;
+%inline %{
 void i2d_ssl_session(BIO *bio, SSL_SESSION *sess) {
     i2d_SSL_SESSION_bio(bio, sess);
 }
+%}
 
+%threadallow ssl_session_read_pem;
+%inline %{
 SSL_SESSION *ssl_session_read_pem(BIO *bio) {
     return PEM_read_bio_SSL_SESSION(bio, NULL, NULL, NULL);
 }
+%}
 
+%threadallow ssl_session_write_pem;
+%inline %{
 int ssl_session_write_pem(SSL_SESSION *sess, BIO *bio) {
     return PEM_write_bio_SSL_SESSION(bio, sess);
 }
only in patch2:
unchanged:
--- m2crypto/SWIG/_asn1.i	2006-03-09 02:50:42.000000000 +0100
+++ m2crypto-0.16/SWIG/_asn1.i	2009-04-06 20:12:58.000000000 +0200
@@ -54,7 +54,9 @@
 %typemap(in) (const void *, int);
 
 %rename(asn1_string_print) ASN1_STRING_print;
+%threadallow ASN1_STRING_print;
 extern int ASN1_STRING_print(BIO *, ASN1_STRING *);
+%threadallow ASN1_STRING_print_ex;
 %rename(asn1_string_print_ex) ASN1_STRING_print_ex;
 extern int ASN1_STRING_print_ex(BIO *, ASN1_STRING *, unsigned long);
 
@@ -69,6 +71,7 @@
 %rename(asn1_utctime_set_string) ASN1_UTCTIME_set_string;
 extern int ASN1_UTCTIME_set_string(ASN1_UTCTIME *, CONST098 char *);
 %rename(asn1_utctime_print) ASN1_UTCTIME_print;
+%threadallow ASN1_UTCTIME_print;
 extern int ASN1_UTCTIME_print(BIO *, ASN1_UTCTIME *);
 
 %rename(asn1_integer_new) ASN1_INTEGER_new;
only in patch2:
unchanged:
--- m2crypto/SWIG/_bio.i	2006-03-08 20:56:46.000000000 +0100
+++ m2crypto-0.16/SWIG/_bio.i	2009-04-06 20:12:58.000000000 +0200
@@ -38,8 +38,10 @@
 %rename(bio_new_file) BIO_new_file;
 extern BIO *BIO_new_file(const char *, const char *);
 %rename(bio_free) BIO_free;
+%threadallow BIO_free;
 extern int BIO_free(BIO *);
 %rename(bio_free_all) BIO_free_all;
+%threadallow BIO_free_all;
 extern void BIO_free_all(BIO *);
 %rename(bio_dup_chain) BIO_dup_chain;
 extern BIO *BIO_dup_chain(BIO *);
@@ -152,7 +154,10 @@
 int bio_reset(BIO *bio) {
     return (int)BIO_reset(bio);
 }
+%}
 
+%threadallow bio_flush;
+%inline %{
 int bio_flush(BIO *bio) {
     return (int)BIO_flush(bio);
 }
@@ -190,7 +195,10 @@
 int bio_get_fd(BIO *bio) {
     return BIO_get_fd(bio, NULL);
 }
+%}
 
+%threadallow bio_do_handshake;
+%inline %{
 int bio_do_handshake(BIO *bio) {
     return BIO_do_handshake(bio);
 }
only in patch2:
unchanged:
--- m2crypto/SWIG/_dh.i	2006-03-08 20:56:46.000000000 +0100
+++ m2crypto-0.16/SWIG/_dh.i	2009-04-06 20:12:58.000000000 +0200
@@ -20,6 +20,7 @@
 %rename(dh_generate_key) DH_generate_key;
 extern int DH_generate_key(DH *);
 %rename(dhparams_print) DHparams_print;
+%threadallow DHparams_print;
 extern int DHparams_print(BIO *, const DH *);
 
 %constant int dh_check_ok             = 0;
@@ -44,7 +45,10 @@
     XXX Still need to check the pointer for sanity? */
     return 1;
 }
+%}
 
+%threadallow dh_read_parameters;
+%inline %{
 DH *dh_read_parameters(BIO *bio) {
     return PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
 }
only in patch2:
unchanged:
--- m2crypto/SWIG/_dsa.i	2006-05-10 23:31:24.000000000 +0200
+++ m2crypto-0.16/SWIG/_dsa.i	2009-04-06 20:12:58.000000000 +0200
@@ -153,7 +153,10 @@
     Py_INCREF(Py_None);
     return Py_None;
 }
+%}
 
+%threadallow dsa_read_params;
+%inline %{
 DSA *dsa_read_params(BIO *f, PyObject *pyfunc) {
     DSA *ret;
 
@@ -162,11 +165,17 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow dsa_write_params_bio;
+%inline %{
 int dsa_write_params_bio(DSA* dsa, BIO* f) {
     return PEM_write_bio_DSAparams(f, dsa);
 }
+%}
 
+%threadallow dsa_write_key_bio;
+%inline %{
 int dsa_write_key_bio(DSA* dsa, BIO* f, EVP_CIPHER *cipher, PyObject *pyfunc) {
     int ret;
 
@@ -176,7 +185,10 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow dsa_write_key_bio_no_cipher;
+%inline %{
 int dsa_write_key_bio_no_cipher(DSA* dsa, BIO* f, PyObject *pyfunc) {
     int ret;
 
@@ -186,11 +198,17 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow dsa_write_pub_key_bio;
+%inline %{
 int dsa_write_pub_key_bio(DSA* dsa, BIO* f) {
     return PEM_write_bio_DSA_PUBKEY(f, dsa);
 }
+%}
 
+%threadallow dsa_read_key;
+%inline %{
 DSA *dsa_read_key(BIO *f, PyObject *pyfunc) {
     DSA *ret;
 
@@ -199,7 +217,10 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow dsa_read_pub_key;
+%inline %{
 DSA *dsa_read_pub_key(BIO *f, PyObject *pyfunc) {
     DSA *ret;
 
only in patch2:
unchanged:
--- m2crypto/SWIG/_ec.i	2009-04-06 20:10:02.000000000 +0200
+++ m2crypto-0.16/SWIG/_ec.i	2009-04-06 20:12:58.000000000 +0200
@@ -149,15 +149,24 @@
 
     return pyo;
 }
+%}
 
+%threadallow ec_key_read_pubkey;
+%inline %{
 EC_KEY *ec_key_read_pubkey(BIO *f) {
     return PEM_read_bio_EC_PUBKEY(f, NULL, NULL, NULL);   
 }
+%}
 
+%threadallow ec_key_write_pubkey;
+%inline %{
 int ec_key_write_pubkey(EC_KEY *key, BIO *f) {
     return PEM_write_bio_EC_PUBKEY(f, key );
 }
+%}
 
+%threadallow ec_key_read_bio;
+%inline %{
 EC_KEY *ec_key_read_bio(BIO *f, PyObject *pyfunc) {
     EC_KEY *ret;
 
@@ -166,7 +175,10 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow ec_key_write_bio;
+%inline %{
 int ec_key_write_bio(EC_KEY *key, BIO *f, EVP_CIPHER *cipher, PyObject *pyfunc) {
     int ret;
 
@@ -176,7 +188,10 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow ec_key_write_bio_no_cipher;
+%inline %{
 int ec_key_write_bio_no_cipher(EC_KEY *key, BIO *f, PyObject *pyfunc) {
     int ret;
 
only in patch2:
unchanged:
--- m2crypto/SWIG/_evp.i	2006-05-02 23:00:53.000000000 +0200
+++ m2crypto-0.16/SWIG/_evp.i	2009-04-06 20:12:58.000000000 +0200
@@ -395,7 +395,10 @@
 
     return EVP_VerifyFinal(ctx, kbuf, len, pkey);
 }
+%}
 
+%threadallow pkey_write_pem_no_cipher;
+%inline %{
 int pkey_write_pem_no_cipher(EVP_PKEY *pkey, BIO *f, PyObject *pyfunc) {
     int ret;
 
@@ -405,7 +408,10 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow pkey_write_pem;
+%inline %{
 int pkey_write_pem(EVP_PKEY *pkey, BIO *f, EVP_CIPHER *cipher, PyObject *pyfunc) {
     int ret;
 
@@ -415,7 +421,10 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow pkey_read_pem;
+%inline %{
 EVP_PKEY *pkey_read_pem(BIO *f, PyObject *pyfunc) {
     EVP_PKEY *pk;
 
only in patch2:
unchanged:
--- m2crypto/SWIG/_m2crypto.i	2009-04-06 20:12:04.000000000 +0200
+++ m2crypto-0.16/SWIG/_m2crypto.i	2009-04-06 20:22:11.000000000 +0200
@@ -5,7 +5,12 @@
  * Copyright (C) 2004-2006 OSAF. All Rights Reserved.
  */
 
-%module _m2crypto
+%module(threads=1) _m2crypto
+/* We really don't need threadblock (PyGILState_Ensure() etc.) anywhere.
+   Disable threadallow as well, only enable it for operations likely to
+   block. */
+%nothreadblock;
+%nothreadallow;
 
 %{
 #include <openssl/err.h>
only in patch2:
unchanged:
--- m2crypto/SWIG/_pkcs7.i	2006-04-24 23:57:42.000000000 +0200
+++ m2crypto-0.16/SWIG/_pkcs7.i	2009-04-06 20:12:58.000000000 +0200
@@ -48,7 +48,10 @@
     Py_INCREF(smime_err);
     _smime_err = smime_err;
 }
+%}
 
+%threadallow pkcs7_encrypt;
+%inline %{
 PKCS7 *pkcs7_encrypt(STACK *stack, BIO *bio, EVP_CIPHER *cipher, int flags) {
     return PKCS7_encrypt((STACK_OF(X509) *)stack, bio, cipher, flags);
 }
@@ -80,15 +83,24 @@
     PyMem_Free(outbuf);
     return ret;
 }
+%}
 
+%threadallow pkcs7_sign0;
+%inline %{
 PKCS7 *pkcs7_sign0(X509 *x509, EVP_PKEY *pkey, BIO *bio, int flags) {
     return PKCS7_sign(x509, pkey, NULL, bio, flags);
 }
+%}
 
+%threadallow pkcs7_sign1;
+%inline %{
 PKCS7 *pkcs7_sign1(X509 *x509, EVP_PKEY *pkey, STACK *stack, BIO *bio, int flags) {
     return PKCS7_sign(x509, pkey, (STACK_OF(X509) *)stack, bio, flags);
 }
+%}
 
+%threadallow pkcs7_verify1;
+%inline %{
 PyObject *pkcs7_verify1(PKCS7 *pkcs7, STACK *stack, X509_STORE *store, BIO *data, int flags) {
     int outlen;
     char *outbuf;
@@ -121,11 +133,17 @@
 PyObject *pkcs7_verify0(PKCS7 *pkcs7, STACK *stack, X509_STORE *store, int flags) {
     return pkcs7_verify1(pkcs7, stack, store, NULL, flags);
 }
+%}
 
+%threadallow smime_write_pkcs7_multi;
+%inline %{
 int smime_write_pkcs7_multi(BIO *bio, PKCS7 *pkcs7, BIO *data, int flags) {
     return SMIME_write_PKCS7(bio, pkcs7, data, flags | PKCS7_DETACHED);
 }
+%}
 
+%threadallow smime_write_pkcs7;
+%inline %{
 int smime_write_pkcs7(BIO *bio, PKCS7 *pkcs7, int flags) {
     return SMIME_write_PKCS7(bio, pkcs7, NULL, flags);
 }
@@ -135,7 +153,10 @@
     PKCS7 *p7;
     PyObject *tuple, *_p7, *_BIO;
 
-    if (!(p7=SMIME_read_PKCS7(bio, &bcont))) {
+    Py_BEGIN_ALLOW_THREADS
+    p7=SMIME_read_PKCS7(bio, &bcont);
+    Py_END_ALLOW_THREADS
+    if (!p7) {
         PyErr_SetString(_smime_err, ERR_reason_error_string(ERR_get_error()));
         return NULL;
     }
@@ -154,19 +175,31 @@
     }
     return tuple;
 }
+%}
 
+%threadallow pkcs7_read_bio;
+%inline %{
 PKCS7 *pkcs7_read_bio(BIO *bio) {
     return PEM_read_bio_PKCS7(bio, NULL, NULL, NULL);
 }
+%}
 
+%threadallow pkcs7_read_bio_der;
+%inline %{
 PKCS7 *pkcs7_read_bio_der(BIO *bio) {
     return d2i_PKCS7_bio(bio, NULL);
 }
+%}
 
+%threadallow pkcs7_write_bio;
+%inline %{
 int pkcs7_write_bio(PKCS7 *pkcs7, BIO* bio) {
     return PEM_write_bio_PKCS7(bio, pkcs7);
 }
+%}
 
+%threadallow pkcs7_write_bio_der;
+%inline %{
 int pkcs7_write_bio_der(PKCS7 *pkcs7, BIO *bio) {
     return i2d_PKCS7_bio(bio, pkcs7);
 }
@@ -178,7 +211,10 @@
 const char *pkcs7_type_sn(PKCS7 *pkcs7) {
     return OBJ_nid2sn(OBJ_obj2nid(pkcs7->type));
 }
+%}
 
+%threadallow smime_crlf_copy;
+%inline %{
 int smime_crlf_copy(BIO *in, BIO *out) {
     return SMIME_crlf_copy(in, out, PKCS7_TEXT);
 }
only in patch2:
unchanged:
--- m2crypto/SWIG/_rsa.i	2006-05-02 23:00:53.000000000 +0200
+++ m2crypto-0.16/SWIG/_rsa.i	2009-04-06 20:12:58.000000000 +0200
@@ -46,7 +46,10 @@
     Py_INCREF(rsa_err);
     _rsa_err = rsa_err;
 }
+%}
 
+%threadallow rsa_read_key;
+%inline %{
 RSA *rsa_read_key(BIO *f, PyObject *pyfunc) {
     RSA *rsa;
 
@@ -55,7 +58,10 @@
     Py_DECREF(pyfunc);
     return rsa;
 }
+%}
 
+%threadallow rsa_write_key;
+%inline %{
 int rsa_write_key(RSA *rsa, BIO *f, EVP_CIPHER *cipher, PyObject *pyfunc) {
     int ret;
 
@@ -65,7 +71,10 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow rsa_write_key_no_cipher;
+%inline %{
 int rsa_write_key_no_cipher(RSA *rsa, BIO *f, PyObject *pyfunc) {
     int ret;
 
@@ -75,11 +84,17 @@
     Py_DECREF(pyfunc);
     return ret;
 }
+%}
 
+%threadallow rsa_read_pub_key;
+%inline %{
 RSA *rsa_read_pub_key(BIO *f) {
     return PEM_read_bio_RSA_PUBKEY(f, NULL, NULL, NULL);   
 }
+%}
 
+%threadallow rsa_write_pub_key;
+%inline %{
 int rsa_write_pub_key(RSA *rsa, BIO *f) {
     return PEM_write_bio_RSA_PUBKEY(f, rsa);
 }
@@ -361,7 +376,10 @@
 int rsa_check_pub_key(RSA *rsa) {
     return (rsa->e) && (rsa->n);
 }
+%}
 
+%threadallow rsa_write_key_der;
+%inline %{
 int rsa_write_key_der(RSA *rsa, BIO *bio) {
     return i2d_RSAPrivateKey_bio(bio, rsa);
 }
only in patch2:
unchanged:
--- m2crypto/SWIG/_x509.i	2009-04-06 20:10:02.000000000 +0200
+++ m2crypto-0.16/SWIG/_x509.i	2009-04-06 20:19:08.000000000 +0200
@@ -34,8 +34,10 @@
 extern void X509_CRL_free(X509_CRL *);
 
 %rename(x509_print) X509_print;
+%threadallow X509_print;
 extern int X509_print(BIO *, X509 *);
 %rename(x509_crl_print) X509_CRL_print;
+%threadallow X509_CRL_print;
 extern int X509_CRL_print(BIO *, X509_CRL *);
 
 %rename(x509_get_serial_number) X509_get_serialNumber;
@@ -92,6 +94,7 @@
 extern X509_check_trust(X509 *, int, int);
 
 %rename(x509_write_pem) PEM_write_bio_X509;
+%threadallow PEM_write_bio_X509;
 extern int PEM_write_bio_X509(BIO *, X509 *);
 %rename(x509_write_pem_file) PEM_write_X509;
 extern int PEM_write_X509(FILE *, X509 *);
@@ -108,6 +111,7 @@
 %rename(x509_get_ext) X509_get_ext;
 extern X509_EXTENSION *X509_get_ext(X509 *, int);
 %rename(x509_ext_print) X509V3_EXT_print;
+%threadallow X509V3_EXT_print;
 extern int X509V3_EXT_print(BIO *, X509_EXTENSION *, unsigned long, int);
 
 %rename(x509_name_new) X509_NAME_new;
@@ -115,6 +119,7 @@
 %rename(x509_name_free) X509_NAME_free;
 extern void X509_NAME_free(X509_NAME *);
 %rename(x509_name_print) X509_NAME_print;
+%threadallow X509_NAME_print;
 extern int X509_NAME_print(BIO *, X509_NAME *, int);
 %rename(x509_name_get_entry) X509_NAME_get_entry;
 extern X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *, int);
@@ -129,6 +134,7 @@
 %rename(x509_name_add_entry_by_nid) X509_NAME_add_entry_by_NID;
 extern int X509_NAME_add_entry_by_NID(X509_NAME *, int, int, unsigned char *, int, int, int );
 %rename(x509_name_print_ex) X509_NAME_print_ex;
+%threadallow X509_NAME_print_ex;
 extern int X509_NAME_print_ex(BIO *, X509_NAME *, int, unsigned long);
 %rename(x509_name_print_ex_fp) X509_NAME_print_ex_fp;
 extern int X509_NAME_print_ex_fp(FILE *, X509_NAME *, int, unsigned long);
@@ -155,6 +161,7 @@
 %rename(x509_req_free) X509_REQ_free;
 extern void X509_REQ_free(X509_REQ *);
 %rename(x509_req_print) X509_REQ_print;
+%threadallow X509_REQ_print;
 extern int X509_REQ_print(BIO *, X509_REQ *);
 
 %rename(x509_req_get_pubkey) X509_REQ_get_pubkey;
@@ -170,6 +177,7 @@
 extern int X509_REQ_sign(X509_REQ *, EVP_PKEY *, const EVP_MD *);
 
 %rename(i2d_x509) i2d_X509_bio;
+%threadallow i2d_X509_bio;
 extern int i2d_X509_bio(BIO *, X509 *);
 
 %rename(x509_store_new) X509_STORE_new;
@@ -272,19 +280,31 @@
     Py_INCREF(x509_err);
     _x509_err = x509_err;
 }
+%}
 
+%threadallow x509_read_pem;
+%inline %{
 X509 *x509_read_pem(BIO *bio) {
     return PEM_read_bio_X509(bio, NULL, NULL, NULL);
 }
+%}
 
+%threadallow x509_req_read_pem;
+%inline %{
 X509_REQ *x509_req_read_pem(BIO *bio) {
     return PEM_read_bio_X509_REQ(bio, NULL, NULL, NULL);
 }
+%}
 
+%threadallow x509_req_write_pem;
+%inline %{
 int x509_req_write_pem(BIO *bio, X509_REQ *x) {
     return PEM_write_bio_X509_REQ(bio, x);
 }
+%}
 
+%threadallow x509_crl_read_pem;
+%inline %{
 X509_CRL *x509_crl_read_pem(BIO *bio) {
     return PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
 }