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); }