lib3026.c (5228B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 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 #include "first.h" 25 26 #define NUM_THREADS 100 27 28 #ifdef _WIN32 29 #if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) 30 static DWORD WINAPI t3026_run_thread(LPVOID ptr) 31 #else 32 #include <process.h> 33 static unsigned int WINAPI t3026_run_thread(void *ptr) 34 #endif 35 { 36 CURLcode *result = ptr; 37 38 *result = curl_global_init(CURL_GLOBAL_ALL); 39 if(*result == CURLE_OK) 40 curl_global_cleanup(); 41 42 return 0; 43 } 44 45 static CURLcode test_lib3026(char *URL) 46 { 47 #if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) 48 typedef HANDLE curl_win_thread_handle_t; 49 #else 50 typedef uintptr_t curl_win_thread_handle_t; 51 #endif 52 CURLcode results[NUM_THREADS]; 53 curl_win_thread_handle_t ths[NUM_THREADS]; 54 unsigned tid_count = NUM_THREADS, i; 55 CURLcode test_failure = CURLE_OK; 56 curl_version_info_data *ver; 57 (void) URL; 58 59 ver = curl_version_info(CURLVERSION_NOW); 60 if((ver->features & CURL_VERSION_THREADSAFE) == 0) { 61 curl_mfprintf(stderr, "%s:%d On Windows but the " 62 "CURL_VERSION_THREADSAFE feature flag is not set\n", 63 __FILE__, __LINE__); 64 return TEST_ERR_MAJOR_BAD; 65 } 66 67 for(i = 0; i < tid_count; i++) { 68 curl_win_thread_handle_t th; 69 results[i] = CURL_LAST; /* initialize with invalid value */ 70 #if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) 71 th = CreateThread(NULL, 0, t3026_run_thread, &results[i], 0, NULL); 72 #else 73 th = _beginthreadex(NULL, 0, t3026_run_thread, &results[i], 0, NULL); 74 #endif 75 if(!th) { 76 curl_mfprintf(stderr, "%s:%d Couldn't create thread, errno %lu\n", 77 __FILE__, __LINE__, GetLastError()); 78 tid_count = i; 79 test_failure = TEST_ERR_MAJOR_BAD; 80 goto cleanup; 81 } 82 ths[i] = th; 83 } 84 85 cleanup: 86 for(i = 0; i < tid_count; i++) { 87 WaitForSingleObject((HANDLE)ths[i], INFINITE); 88 CloseHandle((HANDLE)ths[i]); 89 if(results[i] != CURLE_OK) { 90 curl_mfprintf(stderr, "%s:%d thread[%u]: curl_global_init() failed," 91 "with code %d (%s)\n", __FILE__, __LINE__, 92 i, (int) results[i], curl_easy_strerror(results[i])); 93 test_failure = TEST_ERR_MAJOR_BAD; 94 } 95 } 96 97 return test_failure; 98 } 99 100 #elif defined(HAVE_PTHREAD_H) 101 #include <pthread.h> 102 103 static void *t3026_run_thread(void *ptr) 104 { 105 CURLcode *result = ptr; 106 107 *result = curl_global_init(CURL_GLOBAL_ALL); 108 if(*result == CURLE_OK) 109 curl_global_cleanup(); 110 111 return NULL; 112 } 113 114 static CURLcode test_lib3026(char *URL) 115 { 116 CURLcode results[NUM_THREADS]; 117 pthread_t tids[NUM_THREADS]; 118 unsigned tid_count = NUM_THREADS, i; 119 CURLcode test_failure = CURLE_OK; 120 curl_version_info_data *ver; 121 (void) URL; 122 123 ver = curl_version_info(CURLVERSION_NOW); 124 if((ver->features & CURL_VERSION_THREADSAFE) == 0) { 125 curl_mfprintf(stderr, "%s:%d Have pthread but the " 126 "CURL_VERSION_THREADSAFE feature flag is not set\n", 127 __FILE__, __LINE__); 128 return TEST_ERR_MAJOR_BAD; 129 } 130 131 for(i = 0; i < tid_count; i++) { 132 int res; 133 results[i] = CURL_LAST; /* initialize with invalid value */ 134 res = pthread_create(&tids[i], NULL, t3026_run_thread, &results[i]); 135 if(res) { 136 curl_mfprintf(stderr, "%s:%d Couldn't create thread, errno %d\n", 137 __FILE__, __LINE__, res); 138 tid_count = i; 139 test_failure = TEST_ERR_MAJOR_BAD; 140 goto cleanup; 141 } 142 } 143 144 cleanup: 145 for(i = 0; i < tid_count; i++) { 146 pthread_join(tids[i], NULL); 147 if(results[i] != CURLE_OK) { 148 curl_mfprintf(stderr, "%s:%d thread[%u]: curl_global_init() failed," 149 "with code %d (%s)\n", __FILE__, __LINE__, 150 i, (int) results[i], curl_easy_strerror(results[i])); 151 test_failure = TEST_ERR_MAJOR_BAD; 152 } 153 } 154 155 return test_failure; 156 } 157 158 #else /* without pthread or Windows, this test doesn't work */ 159 static CURLcode test_lib3026(char *URL) 160 { 161 curl_version_info_data *ver; 162 (void)URL; 163 164 ver = curl_version_info(CURLVERSION_NOW); 165 if((ver->features & CURL_VERSION_THREADSAFE) != 0) { 166 curl_mfprintf(stderr, "%s:%d No pthread but the " 167 "CURL_VERSION_THREADSAFE feature flag is set\n", 168 __FILE__, __LINE__); 169 return TEST_ERR_MAJOR_BAD; 170 } 171 return CURLE_OK; 172 } 173 #endif