diff --git a/docs/examples/Makefile.am b/docs/examples/Makefile.am index 5df1e593d..7e71c2846 100644 --- a/docs/examples/Makefile.am +++ b/docs/examples/Makefile.am @@ -10,7 +10,7 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \ post-callback.c multi-app.c multi-double.c multi-single.c \ multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \ multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \ - anyauthput.c htmltitle.cc htmltidy.c + anyauthput.c htmltitle.cc htmltidy.c opensslthreadlock.c all: @echo "done" diff --git a/docs/examples/opensslthreadlock.c b/docs/examples/opensslthreadlock.c new file mode 100644 index 000000000..82de206da --- /dev/null +++ b/docs/examples/opensslthreadlock.c @@ -0,0 +1,77 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * $Id$ + * + * Example source code to show one way to set the necessary OpenSSL locking + * callbacks if you want to do multi-threaded transfers with HTTPS/FTPS with + * libcurl built to use OpenSSL. + * + * This is not a complete stand-alone example. + * + * Author: Jeremy Brown + */ + +#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); + /* exit(-1); */ + } + +/* 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 thread_setup(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 thread_cleanup(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; +}