Home | History | Annotate | Download | only in examples
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel (at) haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at http://curl.haxx.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  ***************************************************************************/
     22 /* Example source code to show one way to set the necessary OpenSSL locking
     23  * callbacks if you want to do multi-threaded transfers with HTTPS/FTPS with
     24  * libcurl built to use OpenSSL.
     25  *
     26  * This is not a complete stand-alone example.
     27  *
     28  * Author: Jeremy Brown
     29  */
     30 
     31 
     32 #include <stdio.h>
     33 #include <pthread.h>
     34 #include <openssl/err.h>
     35 
     36 #define MUTEX_TYPE       pthread_mutex_t
     37 #define MUTEX_SETUP(x)   pthread_mutex_init(&(x), NULL)
     38 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
     39 #define MUTEX_LOCK(x)    pthread_mutex_lock(&(x))
     40 #define MUTEX_UNLOCK(x)  pthread_mutex_unlock(&(x))
     41 #define THREAD_ID        pthread_self(  )
     42 
     43 
     44 void handle_error(const char *file, int lineno, const char *msg){
     45      fprintf(stderr, "** %s:%d %s\n", file, lineno, msg);
     46      ERR_print_errors_fp(stderr);
     47      /* exit(-1); */
     48  }
     49 
     50 /* This array will store all of the mutexes available to OpenSSL. */
     51 static MUTEX_TYPE *mutex_buf= NULL;
     52 
     53 
     54 static void locking_function(int mode, int n, const char * file, int line)
     55 {
     56   if (mode & CRYPTO_LOCK)
     57     MUTEX_LOCK(mutex_buf[n]);
     58   else
     59     MUTEX_UNLOCK(mutex_buf[n]);
     60 }
     61 
     62 static unsigned long id_function(void)
     63 {
     64   return ((unsigned long)THREAD_ID);
     65 }
     66 
     67 int thread_setup(void)
     68 {
     69   int i;
     70 
     71   mutex_buf = malloc(CRYPTO_num_locks(  ) * sizeof(MUTEX_TYPE));
     72   if (!mutex_buf)
     73     return 0;
     74   for (i = 0;  i < CRYPTO_num_locks(  );  i++)
     75     MUTEX_SETUP(mutex_buf[i]);
     76   CRYPTO_set_id_callback(id_function);
     77   CRYPTO_set_locking_callback(locking_function);
     78   return 1;
     79 }
     80 
     81 int thread_cleanup(void)
     82 {
     83   int i;
     84 
     85   if (!mutex_buf)
     86     return 0;
     87   CRYPTO_set_id_callback(NULL);
     88   CRYPTO_set_locking_callback(NULL);
     89   for (i = 0;  i < CRYPTO_num_locks(  );  i++)
     90     MUTEX_CLEANUP(mutex_buf[i]);
     91   free(mutex_buf);
     92   mutex_buf = NULL;
     93   return 1;
     94 }
     95