--- pyOpenSSL-0.6/src/crypto/crypto.c.threadsafe 2005-07-09 21:53:17.000000000 -0400 +++ pyOpenSSL-0.6/src/crypto/crypto.c 2005-07-09 22:00:32.000000000 -0400 @@ -668,6 +668,71 @@ { NULL, NULL } }; + +/* Unashamedly stolen from http://curl.haxx.se/mail/lib-2005-05/0062.html */ + + +#define MUTEX_TYPE pthread_mutex_t +#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) +#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) +#define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) +#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) +#define THREAD_ID pthread_self() + + +void handle_error(const char *file, int lineno, const char *msg) +{ + fprintf(stderr, "** %s:%i %s\n", file, lineno, msg); + ERR_print_errors_fp(stderr); +} + + +/* This array will store all of the mutexes available to OpenSSL. */ +static MUTEX_TYPE *mutex_buf = NULL; + + +static void locking_function(int mode, int n, const char * file, int line) +{ + if (mode & CRYPTO_LOCK) + MUTEX_LOCK(mutex_buf[n]); + else + MUTEX_UNLOCK(mutex_buf[n]); +} + +static unsigned long id_function(void) +{ + return ((unsigned long)THREAD_ID); +} + +int init_openssl_threads(void) +{ + int i; + + mutex_buf = (MUTEX_TYPE *)malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); + if (!mutex_buf) + return 0; + for (i = 0; i < CRYPTO_num_locks(); i++) + MUTEX_SETUP(mutex_buf[i]); + CRYPTO_set_id_callback(id_function); + CRYPTO_set_locking_callback(locking_function); + return 1; +} + +int deinit_openssl_threads(void) +{ + int i; + + if (!mutex_buf) + return 0; + CRYPTO_set_id_callback(NULL); + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) + MUTEX_CLEANUP(mutex_buf[i]); + free(mutex_buf); + mutex_buf = NULL; + return 1; +} + /* * Initialize crypto sub module * @@ -713,6 +775,8 @@ PyModule_AddIntConstant(module, "TYPE_DSA", crypto_TYPE_DSA); dict = PyModule_GetDict(module); + if (!init_openssl_threads()) + goto error; if (!init_crypto_x509(dict)) goto error; if (!init_crypto_x509name(dict))