opensslthreadlock.c 2.7 KB

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