lib586.c (6496B)
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 #include "memdebug.h" 27 28 #define THREADS 2 29 30 /* struct containing data of a thread */ 31 struct t586_Tdata { 32 CURLSH *share; 33 char *url; 34 }; 35 36 struct t586_userdata { 37 const char *text; 38 int counter; 39 }; 40 41 /* lock callback */ 42 static void t586_test_lock(CURL *handle, curl_lock_data data, 43 curl_lock_access laccess, void *useptr) 44 { 45 const char *what; 46 struct t586_userdata *user = (struct t586_userdata *)useptr; 47 48 (void)handle; 49 (void)laccess; 50 51 switch(data) { 52 case CURL_LOCK_DATA_SHARE: 53 what = "share"; 54 break; 55 case CURL_LOCK_DATA_DNS: 56 what = "dns"; 57 break; 58 case CURL_LOCK_DATA_COOKIE: 59 what = "cookie"; 60 break; 61 case CURL_LOCK_DATA_SSL_SESSION: 62 what = "ssl_session"; 63 break; 64 default: 65 curl_mfprintf(stderr, "lock: no such data: %d\n", (int)data); 66 return; 67 } 68 curl_mprintf("lock: %-6s [%s]: %d\n", what, user->text, user->counter); 69 user->counter++; 70 } 71 72 /* unlock callback */ 73 static void t586_test_unlock(CURL *handle, curl_lock_data data, void *useptr) 74 { 75 const char *what; 76 struct t586_userdata *user = (struct t586_userdata *)useptr; 77 (void)handle; 78 switch(data) { 79 case CURL_LOCK_DATA_SHARE: 80 what = "share"; 81 break; 82 case CURL_LOCK_DATA_DNS: 83 what = "dns"; 84 break; 85 case CURL_LOCK_DATA_COOKIE: 86 what = "cookie"; 87 break; 88 case CURL_LOCK_DATA_SSL_SESSION: 89 what = "ssl_session"; 90 break; 91 default: 92 curl_mfprintf(stderr, "unlock: no such data: %d\n", (int)data); 93 return; 94 } 95 curl_mprintf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter); 96 user->counter++; 97 } 98 99 /* the dummy thread function */ 100 static void *t586_test_fire(void *ptr) 101 { 102 CURLcode code; 103 struct t586_Tdata *tdata = (struct t586_Tdata*)ptr; 104 CURL *curl; 105 106 curl = curl_easy_init(); 107 if(!curl) { 108 curl_mfprintf(stderr, "curl_easy_init() failed\n"); 109 return NULL; 110 } 111 112 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 113 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 114 curl_easy_setopt(curl, CURLOPT_URL, tdata->url); 115 curl_mprintf("CURLOPT_SHARE\n"); 116 curl_easy_setopt(curl, CURLOPT_SHARE, tdata->share); 117 118 curl_mprintf("PERFORM\n"); 119 code = curl_easy_perform(curl); 120 if(code != CURLE_OK) { 121 int i = 0; 122 curl_mfprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n", 123 tdata->url, i, (int)code); 124 } 125 126 curl_mprintf("CLEANUP\n"); 127 curl_easy_cleanup(curl); 128 129 return NULL; 130 } 131 132 /* test function */ 133 static CURLcode test_lib586(char *URL) 134 { 135 CURLcode res = CURLE_OK; 136 CURLSHcode scode = CURLSHE_OK; 137 char *url; 138 struct t586_Tdata tdata; 139 CURL *curl; 140 CURLSH *share; 141 int i; 142 struct t586_userdata user; 143 144 user.text = "Pigs in space"; 145 user.counter = 0; 146 147 curl_mprintf("GLOBAL_INIT\n"); 148 if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { 149 curl_mfprintf(stderr, "curl_global_init() failed\n"); 150 return TEST_ERR_MAJOR_BAD; 151 } 152 153 /* prepare share */ 154 curl_mprintf("SHARE_INIT\n"); 155 share = curl_share_init(); 156 if(!share) { 157 curl_mfprintf(stderr, "curl_share_init() failed\n"); 158 curl_global_cleanup(); 159 return TEST_ERR_MAJOR_BAD; 160 } 161 162 if(CURLSHE_OK == scode) { 163 curl_mprintf("CURLSHOPT_LOCKFUNC\n"); 164 scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, t586_test_lock); 165 } 166 if(CURLSHE_OK == scode) { 167 curl_mprintf("CURLSHOPT_UNLOCKFUNC\n"); 168 scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, t586_test_unlock); 169 } 170 if(CURLSHE_OK == scode) { 171 curl_mprintf("CURLSHOPT_USERDATA\n"); 172 scode = curl_share_setopt(share, CURLSHOPT_USERDATA, &user); 173 } 174 if(CURLSHE_OK == scode) { 175 curl_mprintf("CURL_LOCK_DATA_SSL_SESSION\n"); 176 scode = curl_share_setopt(share, CURLSHOPT_SHARE, 177 CURL_LOCK_DATA_SSL_SESSION); 178 } 179 180 if(CURLSHE_OK != scode) { 181 curl_mfprintf(stderr, "curl_share_setopt() failed\n"); 182 curl_share_cleanup(share); 183 curl_global_cleanup(); 184 return TEST_ERR_MAJOR_BAD; 185 } 186 187 188 /* start treads */ 189 for(i = 1; i <= THREADS; i++) { 190 191 /* set thread data */ 192 tdata.url = URL; 193 tdata.share = share; 194 195 /* simulate thread, direct call of "thread" function */ 196 curl_mprintf("*** run %d\n",i); 197 t586_test_fire(&tdata); 198 } 199 200 201 /* fetch another one */ 202 curl_mprintf("*** run %d\n", i); 203 curl = curl_easy_init(); 204 if(!curl) { 205 curl_mfprintf(stderr, "curl_easy_init() failed\n"); 206 curl_share_cleanup(share); 207 curl_global_cleanup(); 208 return TEST_ERR_MAJOR_BAD; 209 } 210 211 url = URL; 212 test_setopt(curl, CURLOPT_URL, url); 213 curl_mprintf("CURLOPT_SHARE\n"); 214 test_setopt(curl, CURLOPT_SHARE, share); 215 216 curl_mprintf("PERFORM\n"); 217 res = curl_easy_perform(curl); 218 219 /* try to free share, expect to fail because share is in use */ 220 curl_mprintf("try SHARE_CLEANUP...\n"); 221 scode = curl_share_cleanup(share); 222 if(scode == CURLSHE_OK) { 223 curl_mfprintf(stderr, "curl_share_cleanup succeed but error expected\n"); 224 share = NULL; 225 } 226 else { 227 curl_mprintf("SHARE_CLEANUP failed, correct\n"); 228 } 229 230 test_cleanup: 231 232 /* clean up last handle */ 233 curl_mprintf("CLEANUP\n"); 234 curl_easy_cleanup(curl); 235 236 /* free share */ 237 curl_mprintf("SHARE_CLEANUP\n"); 238 scode = curl_share_cleanup(share); 239 if(scode != CURLSHE_OK) 240 curl_mfprintf(stderr, "curl_share_cleanup failed, code errno %d\n", 241 (int)scode); 242 243 curl_mprintf("GLOBAL_CLEANUP\n"); 244 curl_global_cleanup(); 245 246 return res; 247 }