opensslthreadlock.c 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@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 https://curl.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. /* <DESC>
  23. * one way to set the necessary OpenSSL locking callbacks if you want to do
  24. * multi-threaded transfers with HTTPS/FTPS with libcurl built to use OpenSSL.
  25. * </DESC>
  26. */
  27. /*
  28. * This is not a complete stand-alone example.
  29. *
  30. * Author: Jeremy Brown
  31. */
  32. #include <stdio.h>
  33. #include <pthread.h>
  34. #include <openssl/err.h>
  35. #define MUTEX_TYPE pthread_mutex_t
  36. #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
  37. #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
  38. #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
  39. #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
  40. #define THREAD_ID pthread_self()
  41. void handle_error(const char *file, int lineno, const char *msg)
  42. {
  43. fprintf(stderr, "** %s:%d %s\n", file, lineno, msg);
  44. ERR_print_errors_fp(stderr);
  45. /* exit(-1); */
  46. }
  47. /* This array will store all of the mutexes available to OpenSSL. */
  48. static MUTEX_TYPE *mutex_buf = NULL;
  49. static void locking_function(int mode, int n, const char *file, int line)
  50. {
  51. if(mode & CRYPTO_LOCK)
  52. MUTEX_LOCK(mutex_buf[n]);
  53. else
  54. MUTEX_UNLOCK(mutex_buf[n]);
  55. }
  56. static unsigned long id_function(void)
  57. {
  58. return ((unsigned long)THREAD_ID);
  59. }
  60. int thread_setup(void)
  61. {
  62. int i;
  63. mutex_buf = malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
  64. if(!mutex_buf)
  65. return 0;
  66. for(i = 0; i < CRYPTO_num_locks(); i++)
  67. MUTEX_SETUP(mutex_buf[i]);
  68. CRYPTO_set_id_callback(id_function);
  69. CRYPTO_set_locking_callback(locking_function);
  70. return 1;
  71. }
  72. int thread_cleanup(void)
  73. {
  74. int i;
  75. if(!mutex_buf)
  76. return 0;
  77. CRYPTO_set_id_callback(NULL);
  78. CRYPTO_set_locking_callback(NULL);
  79. for(i = 0; i < CRYPTO_num_locks(); i++)
  80. MUTEX_CLEANUP(mutex_buf[i]);
  81. free(mutex_buf);
  82. mutex_buf = NULL;
  83. return 1;
  84. }