1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * Copyright (C) Hoi-Ho Chan, <hoiho.chan@gmail.com> 10 * 11 * This software is licensed as described in the file COPYING, which 12 * you should have received as part of this distribution. The terms 13 * are also available at https://curl.se/docs/copyright.html. 14 * 15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 16 * copies of the Software, and permit persons to whom the Software is 17 * furnished to do so, under the terms of the COPYING file. 18 * 19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 * KIND, either express or implied. 21 * 22 * SPDX-License-Identifier: curl 23 * 24 ***************************************************************************/ 25#include "curl_setup.h" 26 27#if defined(USE_MBEDTLS) && \ 28 ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \ 29 defined(USE_THREADS_WIN32)) 30 31#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) 32# include <pthread.h> 33# define MBEDTLS_MUTEX_T pthread_mutex_t 34#elif defined(USE_THREADS_WIN32) 35# define MBEDTLS_MUTEX_T HANDLE 36#endif 37 38#include "mbedtls_threadlock.h" 39#include "curl_printf.h" 40#include "curl_memory.h" 41/* The last #include file should be: */ 42#include "memdebug.h" 43 44/* number of thread locks */ 45#define NUMT 2 46 47/* This array will store all of the mutexes available to Mbedtls. */ 48static MBEDTLS_MUTEX_T *mutex_buf = NULL; 49 50int Curl_mbedtlsthreadlock_thread_setup(void) 51{ 52 int i; 53 54 mutex_buf = calloc(1, NUMT * sizeof(MBEDTLS_MUTEX_T)); 55 if(!mutex_buf) 56 return 0; /* error, no number of threads defined */ 57 58 for(i = 0; i < NUMT; i++) { 59#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) 60 if(pthread_mutex_init(&mutex_buf[i], NULL)) 61 return 0; /* pthread_mutex_init failed */ 62#elif defined(USE_THREADS_WIN32) 63 mutex_buf[i] = CreateMutex(0, FALSE, 0); 64 if(mutex_buf[i] == 0) 65 return 0; /* CreateMutex failed */ 66#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ 67 } 68 69 return 1; /* OK */ 70} 71 72int Curl_mbedtlsthreadlock_thread_cleanup(void) 73{ 74 int i; 75 76 if(!mutex_buf) 77 return 0; /* error, no threads locks defined */ 78 79 for(i = 0; i < NUMT; i++) { 80#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) 81 if(pthread_mutex_destroy(&mutex_buf[i])) 82 return 0; /* pthread_mutex_destroy failed */ 83#elif defined(USE_THREADS_WIN32) 84 if(!CloseHandle(mutex_buf[i])) 85 return 0; /* CloseHandle failed */ 86#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ 87 } 88 free(mutex_buf); 89 mutex_buf = NULL; 90 91 return 1; /* OK */ 92} 93 94int Curl_mbedtlsthreadlock_lock_function(int n) 95{ 96 if(n < NUMT) { 97#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) 98 if(pthread_mutex_lock(&mutex_buf[n])) { 99 DEBUGF(fprintf(stderr, 100 "Error: mbedtlsthreadlock_lock_function failed\n")); 101 return 0; /* pthread_mutex_lock failed */ 102 } 103#elif defined(USE_THREADS_WIN32) 104 if(WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED) { 105 DEBUGF(fprintf(stderr, 106 "Error: mbedtlsthreadlock_lock_function failed\n")); 107 return 0; /* pthread_mutex_lock failed */ 108 } 109#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ 110 } 111 return 1; /* OK */ 112} 113 114int Curl_mbedtlsthreadlock_unlock_function(int n) 115{ 116 if(n < NUMT) { 117#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) 118 if(pthread_mutex_unlock(&mutex_buf[n])) { 119 DEBUGF(fprintf(stderr, 120 "Error: mbedtlsthreadlock_unlock_function failed\n")); 121 return 0; /* pthread_mutex_unlock failed */ 122 } 123#elif defined(USE_THREADS_WIN32) 124 if(!ReleaseMutex(mutex_buf[n])) { 125 DEBUGF(fprintf(stderr, 126 "Error: mbedtlsthreadlock_unlock_function failed\n")); 127 return 0; /* pthread_mutex_lock failed */ 128 } 129#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ 130 } 131 return 1; /* OK */ 132} 133 134#endif /* USE_MBEDTLS */ 135