diff options
Diffstat (limited to 'src/testcurl/test_concurrent_stop.c')
-rw-r--r-- | src/testcurl/test_concurrent_stop.c | 188 |
1 files changed, 99 insertions, 89 deletions
diff --git a/src/testcurl/test_concurrent_stop.c b/src/testcurl/test_concurrent_stop.c index 71202add..02f4fffd 100644 --- a/src/testcurl/test_concurrent_stop.c +++ b/src/testcurl/test_concurrent_stop.c | |||
@@ -33,10 +33,10 @@ | |||
33 | #include <pthread.h> | 33 | #include <pthread.h> |
34 | #include "gauger.h" | 34 | #include "gauger.h" |
35 | 35 | ||
36 | #if defined(CPU_COUNT) && (CPU_COUNT+0) < 2 | 36 | #if defined(CPU_COUNT) && (CPU_COUNT + 0) < 2 |
37 | #undef CPU_COUNT | 37 | #undef CPU_COUNT |
38 | #endif | 38 | #endif |
39 | #if !defined(CPU_COUNT) | 39 | #if ! defined(CPU_COUNT) |
40 | #define CPU_COUNT 2 | 40 | #define CPU_COUNT 2 |
41 | #endif | 41 | #endif |
42 | 42 | ||
@@ -81,50 +81,52 @@ thread_watchdog (void *param) | |||
81 | 81 | ||
82 | seconds_passed = 0; | 82 | seconds_passed = 0; |
83 | while (watchdog_continue) /* Poor threads sync, but works for testing. */ | 83 | while (watchdog_continue) /* Poor threads sync, but works for testing. */ |
84 | { | ||
85 | if (0 == sleep (1)) /* Poor accuracy, but enough for testing. */ | ||
86 | seconds_passed++; | ||
87 | if (timeout_val < seconds_passed) | ||
84 | { | 88 | { |
85 | if (0 == sleep (1)) /* Poor accuracy, but enough for testing. */ | 89 | fprintf (stderr, "%s timeout expired.\n", watchdog_obj ? watchdog_obj : |
86 | seconds_passed++; | 90 | "Watchdog"); |
87 | if (timeout_val < seconds_passed) | 91 | fflush (stderr); |
88 | { | 92 | _exit (16); |
89 | fprintf (stderr, "%s timeout expired.\n", watchdog_obj ? watchdog_obj : "Watchdog"); | ||
90 | fflush (stderr); | ||
91 | _exit(16); | ||
92 | } | ||
93 | } | 93 | } |
94 | } | ||
94 | return NULL; | 95 | return NULL; |
95 | } | 96 | } |
96 | 97 | ||
97 | pthread_t watchdog_tid; | 98 | pthread_t watchdog_tid; |
98 | 99 | ||
99 | static void | 100 | static void |
100 | start_watchdog(int timeout, const char *obj_name) | 101 | start_watchdog (int timeout, const char *obj_name) |
101 | { | 102 | { |
102 | watchdog_continue = 1; | 103 | watchdog_continue = 1; |
103 | watchdog_obj = obj_name; | 104 | watchdog_obj = obj_name; |
104 | if (0 != pthread_create(&watchdog_tid, NULL, &thread_watchdog, (void*)(intptr_t)timeout)) | 105 | if (0 != pthread_create (&watchdog_tid, NULL, &thread_watchdog, |
105 | { | 106 | (void*) (intptr_t) timeout)) |
106 | fprintf(stderr, "Failed to start watchdog.\n"); | 107 | { |
107 | _exit (99); | 108 | fprintf (stderr, "Failed to start watchdog.\n"); |
108 | } | 109 | _exit (99); |
110 | } | ||
109 | } | 111 | } |
110 | 112 | ||
111 | static void | 113 | static void |
112 | stop_watchdog(void) | 114 | stop_watchdog (void) |
113 | { | 115 | { |
114 | watchdog_continue = 0; | 116 | watchdog_continue = 0; |
115 | if (0 != pthread_join (watchdog_tid, NULL)) | 117 | if (0 != pthread_join (watchdog_tid, NULL)) |
116 | { | 118 | { |
117 | fprintf(stderr, "Failed to stop watchdog.\n"); | 119 | fprintf (stderr, "Failed to stop watchdog.\n"); |
118 | _exit (99); | 120 | _exit (99); |
119 | } | 121 | } |
120 | } | 122 | } |
121 | 123 | ||
122 | static size_t | 124 | static size_t |
123 | copyBuffer (void *ptr, | 125 | copyBuffer (void *ptr, |
124 | size_t size, size_t nmemb, | 126 | size_t size, size_t nmemb, |
125 | void *ctx) | 127 | void *ctx) |
126 | { | 128 | { |
127 | (void)ptr;(void)ctx; /* Unused. Silent compiler warning. */ | 129 | (void) ptr; (void) ctx; /* Unused. Silent compiler warning. */ |
128 | return size * nmemb; | 130 | return size * nmemb; |
129 | } | 131 | } |
130 | 132 | ||
@@ -142,16 +144,16 @@ ahc_echo (void *cls, | |||
142 | static int ptr; | 144 | static int ptr; |
143 | const char *me = cls; | 145 | const char *me = cls; |
144 | int ret; | 146 | int ret; |
145 | (void)url;(void)version; /* Unused. Silent compiler warning. */ | 147 | (void) url; (void) version; /* Unused. Silent compiler warning. */ |
146 | (void)upload_data;(void)upload_data_size; /* Unused. Silent compiler warning. */ | 148 | (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */ |
147 | 149 | ||
148 | if (0 != strcmp (me, method)) | 150 | if (0 != strcmp (me, method)) |
149 | return MHD_NO; /* unexpected method */ | 151 | return MHD_NO; /* unexpected method */ |
150 | if (&ptr != *unused) | 152 | if (&ptr != *unused) |
151 | { | 153 | { |
152 | *unused = &ptr; | 154 | *unused = &ptr; |
153 | return MHD_YES; | 155 | return MHD_YES; |
154 | } | 156 | } |
155 | *unused = NULL; | 157 | *unused = NULL; |
156 | ret = MHD_queue_response (connection, | 158 | ret = MHD_queue_response (connection, |
157 | MHD_HTTP_OK, | 159 | MHD_HTTP_OK, |
@@ -166,15 +168,15 @@ thread_gets (void *param) | |||
166 | { | 168 | { |
167 | CURL *c; | 169 | CURL *c; |
168 | CURLcode errornum; | 170 | CURLcode errornum; |
169 | char * const url = (char*) param; | 171 | char *const url = (char*) param; |
170 | 172 | ||
171 | c = NULL; | 173 | c = NULL; |
172 | c = curl_easy_init (); | 174 | c = curl_easy_init (); |
173 | if (NULL == c) | 175 | if (NULL == c) |
174 | { | 176 | { |
175 | fprintf(stderr, "curl_easy_init failed.\n"); | 177 | fprintf (stderr, "curl_easy_init failed.\n"); |
176 | _exit(99); | 178 | _exit (99); |
177 | } | 179 | } |
178 | curl_easy_setopt (c, CURLOPT_URL, url); | 180 | curl_easy_setopt (c, CURLOPT_URL, url); |
179 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); | 181 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
180 | curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL); | 182 | curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL); |
@@ -190,62 +192,62 @@ thread_gets (void *param) | |||
190 | crashes on my system! */ | 192 | crashes on my system! */ |
191 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L); | 193 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L); |
192 | while (continue_requesting) | 194 | while (continue_requesting) |
195 | { | ||
196 | errornum = curl_easy_perform (c); | ||
197 | if (CURLE_OK != errornum) | ||
193 | { | 198 | { |
194 | errornum = curl_easy_perform (c); | 199 | curl_easy_cleanup (c); |
195 | if (CURLE_OK != errornum) | 200 | return NULL; |
196 | { | ||
197 | curl_easy_cleanup (c); | ||
198 | return NULL; | ||
199 | } | ||
200 | } | 201 | } |
202 | } | ||
201 | curl_easy_cleanup (c); | 203 | curl_easy_cleanup (c); |
202 | return NULL; | 204 | return NULL; |
203 | } | 205 | } |
204 | 206 | ||
205 | static void * | 207 | static void * |
206 | do_gets (void * param) | 208 | do_gets (void *param) |
207 | { | 209 | { |
208 | int j; | 210 | int j; |
209 | pthread_t par[PAR]; | 211 | pthread_t par[PAR]; |
210 | char url[64]; | 212 | char url[64]; |
211 | int port = (int)(intptr_t)param; | 213 | int port = (int) (intptr_t) param; |
212 | 214 | ||
213 | snprintf (url, | 215 | snprintf (url, |
214 | sizeof (url), | 216 | sizeof (url), |
215 | "http://127.0.0.1:%d/hello_world", | 217 | "http://127.0.0.1:%d/hello_world", |
216 | port); | 218 | port); |
217 | 219 | ||
218 | for (j=0;j<PAR;j++) | 220 | for (j = 0; j<PAR; j++) |
219 | { | 221 | { |
220 | if (0 != pthread_create(&par[j], NULL, &thread_gets, (void*)url)) | 222 | if (0 != pthread_create (&par[j], NULL, &thread_gets, (void*) url)) |
221 | { | ||
222 | fprintf(stderr, "pthread_create failed.\n"); | ||
223 | continue_requesting = 0; | ||
224 | for (j--; j >= 0; j--) | ||
225 | { | ||
226 | pthread_join(par[j], NULL); | ||
227 | } | ||
228 | _exit(99); | ||
229 | } | ||
230 | } | ||
231 | (void)sleep (1); | ||
232 | for (j=0;j<PAR;j++) | ||
233 | { | 223 | { |
234 | pthread_join(par[j], NULL); | 224 | fprintf (stderr, "pthread_create failed.\n"); |
225 | continue_requesting = 0; | ||
226 | for (j--; j >= 0; j--) | ||
227 | { | ||
228 | pthread_join (par[j], NULL); | ||
229 | } | ||
230 | _exit (99); | ||
235 | } | 231 | } |
232 | } | ||
233 | (void) sleep (1); | ||
234 | for (j = 0; j<PAR; j++) | ||
235 | { | ||
236 | pthread_join (par[j], NULL); | ||
237 | } | ||
236 | return NULL; | 238 | return NULL; |
237 | } | 239 | } |
238 | 240 | ||
239 | 241 | ||
240 | pthread_t start_gets(int port) | 242 | pthread_t start_gets (int port) |
241 | { | 243 | { |
242 | pthread_t tid; | 244 | pthread_t tid; |
243 | continue_requesting = 1; | 245 | continue_requesting = 1; |
244 | if (0 != pthread_create(&tid, NULL, &do_gets, (void*)(intptr_t)port)) | 246 | if (0 != pthread_create (&tid, NULL, &do_gets, (void*) (intptr_t) port)) |
245 | { | 247 | { |
246 | fprintf(stderr, "pthread_create failed.\n"); | 248 | fprintf (stderr, "pthread_create failed.\n"); |
247 | _exit(99); | 249 | _exit (99); |
248 | } | 250 | } |
249 | return tid; | 251 | return tid; |
250 | } | 252 | } |
251 | 253 | ||
@@ -257,7 +259,9 @@ testMultithreadedGet (int port, | |||
257 | struct MHD_Daemon *d; | 259 | struct MHD_Daemon *d; |
258 | pthread_t p; | 260 | pthread_t p; |
259 | 261 | ||
260 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag, | 262 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION |
263 | | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | ||
264 | | poll_flag, | ||
261 | port, | 265 | port, |
262 | NULL, NULL, | 266 | NULL, NULL, |
263 | &ahc_echo, "GET", | 267 | &ahc_echo, "GET", |
@@ -265,18 +269,20 @@ testMultithreadedGet (int port, | |||
265 | if (d == NULL) | 269 | if (d == NULL) |
266 | return 16; | 270 | return 16; |
267 | if (0 == port) | 271 | if (0 == port) |
272 | { | ||
273 | const union MHD_DaemonInfo *dinfo; | ||
274 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); | ||
275 | if ((NULL == dinfo) ||(0 == dinfo->port) ) | ||
268 | { | 276 | { |
269 | const union MHD_DaemonInfo *dinfo; | 277 | MHD_stop_daemon (d); return 32; |
270 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); | ||
271 | if (NULL == dinfo || 0 == dinfo->port) | ||
272 | { MHD_stop_daemon (d); return 32; } | ||
273 | port = (int)dinfo->port; | ||
274 | } | 278 | } |
279 | port = (int) dinfo->port; | ||
280 | } | ||
275 | p = start_gets (port); | 281 | p = start_gets (port); |
276 | (void)sleep (1); | 282 | (void) sleep (1); |
277 | start_watchdog(10, "daemon_stop() in testMultithreadedGet"); | 283 | start_watchdog (10, "daemon_stop() in testMultithreadedGet"); |
278 | MHD_stop_daemon (d); | 284 | MHD_stop_daemon (d); |
279 | stop_watchdog(); | 285 | stop_watchdog (); |
280 | continue_requesting = 0; | 286 | continue_requesting = 0; |
281 | pthread_join (p, NULL); | 287 | pthread_join (p, NULL); |
282 | return 0; | 288 | return 0; |
@@ -290,7 +296,8 @@ testMultithreadedPoolGet (int port, | |||
290 | struct MHD_Daemon *d; | 296 | struct MHD_Daemon *d; |
291 | pthread_t p; | 297 | pthread_t p; |
292 | 298 | ||
293 | d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag, | 299 | d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG |
300 | | poll_flag, | ||
294 | port, | 301 | port, |
295 | NULL, NULL, | 302 | NULL, NULL, |
296 | &ahc_echo, "GET", | 303 | &ahc_echo, "GET", |
@@ -299,18 +306,20 @@ testMultithreadedPoolGet (int port, | |||
299 | if (d == NULL) | 306 | if (d == NULL) |
300 | return 16; | 307 | return 16; |
301 | if (0 == port) | 308 | if (0 == port) |
309 | { | ||
310 | const union MHD_DaemonInfo *dinfo; | ||
311 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); | ||
312 | if ((NULL == dinfo) ||(0 == dinfo->port) ) | ||
302 | { | 313 | { |
303 | const union MHD_DaemonInfo *dinfo; | 314 | MHD_stop_daemon (d); return 32; |
304 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); | ||
305 | if (NULL == dinfo || 0 == dinfo->port) | ||
306 | { MHD_stop_daemon (d); return 32; } | ||
307 | port = (int)dinfo->port; | ||
308 | } | 315 | } |
316 | port = (int) dinfo->port; | ||
317 | } | ||
309 | p = start_gets (port); | 318 | p = start_gets (port); |
310 | (void)sleep (1); | 319 | (void) sleep (1); |
311 | start_watchdog(10, "daemon_stop() in testMultithreadedPoolGet"); | 320 | start_watchdog (10, "daemon_stop() in testMultithreadedPoolGet"); |
312 | MHD_stop_daemon (d); | 321 | MHD_stop_daemon (d); |
313 | stop_watchdog(); | 322 | stop_watchdog (); |
314 | continue_requesting = 0; | 323 | continue_requesting = 0; |
315 | pthread_join (p, NULL); | 324 | pthread_join (p, NULL); |
316 | return 0; | 325 | return 0; |
@@ -322,8 +331,8 @@ main (int argc, char *const *argv) | |||
322 | { | 331 | { |
323 | unsigned int errorCount = 0; | 332 | unsigned int errorCount = 0; |
324 | int port; | 333 | int port; |
325 | (void)argc; /* Unused. Silent compiler warning. */ | 334 | (void) argc; /* Unused. Silent compiler warning. */ |
326 | (void)argv; /* Unused. Silent compiler warning. */ | 335 | (void) argv; /* Unused. Silent compiler warning. */ |
327 | 336 | ||
328 | if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) | 337 | if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) |
329 | port = 0; | 338 | port = 0; |
@@ -333,15 +342,16 @@ main (int argc, char *const *argv) | |||
333 | /* Do reuse connection, otherwise all available local ports may exhausted. */ | 342 | /* Do reuse connection, otherwise all available local ports may exhausted. */ |
334 | oneone = 1; | 343 | oneone = 1; |
335 | 344 | ||
336 | if (0 != port && oneone) | 345 | if ((0 != port)&& oneone) |
337 | port += 5; | 346 | port += 5; |
338 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) | 347 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) |
339 | return 2; | 348 | return 2; |
340 | response = MHD_create_response_from_buffer (strlen ("/hello_world"), | 349 | response = MHD_create_response_from_buffer (strlen ("/hello_world"), |
341 | "/hello_world", | 350 | "/hello_world", |
342 | MHD_RESPMEM_MUST_COPY); | 351 | MHD_RESPMEM_MUST_COPY); |
343 | errorCount += testMultithreadedGet (port, 0); | 352 | errorCount += testMultithreadedGet (port, 0); |
344 | if (0 != port) port++; | 353 | if (0 != port) |
354 | port++; | ||
345 | errorCount += testMultithreadedPoolGet (port, 0); | 355 | errorCount += testMultithreadedPoolGet (port, 0); |
346 | MHD_destroy_response (response); | 356 | MHD_destroy_response (response); |
347 | if (errorCount != 0) | 357 | if (errorCount != 0) |