diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/daemon/daemon.c | 83 | ||||
-rw-r--r-- | src/daemon/internal.h | 2 | ||||
-rw-r--r-- | src/include/microhttpd.h | 2 | ||||
-rw-r--r-- | src/testcurl/daemontest_iplimit.c | 8 | ||||
-rw-r--r-- | src/testcurl/https/mhds_multi_daemon_test.c | 5 | ||||
-rw-r--r-- | src/testcurl/https/tls_extension_test.c | 10 | ||||
-rw-r--r-- | src/testcurl/https/tls_test_common.c | 18 |
8 files changed, 74 insertions, 59 deletions
@@ -1,5 +1,8 @@ | |||
1 | Tue Mar 17 01:19:50 MDT 2009 | ||
2 | Added support for thread-pools. -CG/RA | ||
3 | |||
1 | Mon Mar 2 23:44:08 MST 2009 | 4 | Mon Mar 2 23:44:08 MST 2009 |
2 | Fixd problem with 64-bit upload and download sizes and | 5 | Fixed problem with 64-bit upload and download sizes and |
3 | "-1" being used to indicate "unknown" by introducing | 6 | "-1" being used to indicate "unknown" by introducing |
4 | new 64-bit constant "MHD_SIZE_UNKNOWN". -CG/DC | 7 | new 64-bit constant "MHD_SIZE_UNKNOWN". -CG/DC |
5 | 8 | ||
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 18775c46..ab829847 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c | |||
@@ -1138,6 +1138,7 @@ MHD_start_daemon_va (unsigned int options, | |||
1138 | FPRINTF (stderr, | 1138 | FPRINTF (stderr, |
1139 | "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n"); | 1139 | "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n"); |
1140 | #endif | 1140 | #endif |
1141 | free (retVal); | ||
1141 | return NULL; | 1142 | return NULL; |
1142 | } | 1143 | } |
1143 | 1144 | ||
@@ -1252,7 +1253,7 @@ MHD_start_daemon_va (unsigned int options, | |||
1252 | if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || | 1253 | if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || |
1253 | ((0 != (options & MHD_USE_SELECT_INTERNALLY)) | 1254 | ((0 != (options & MHD_USE_SELECT_INTERNALLY)) |
1254 | && (0 == retVal->worker_pool_size))) | 1255 | && (0 == retVal->worker_pool_size))) |
1255 | && (0 != | 1256 | && (0 != |
1256 | pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal))) | 1257 | pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal))) |
1257 | { | 1258 | { |
1258 | #if HAVE_MESSAGES | 1259 | #if HAVE_MESSAGES |
@@ -1274,28 +1275,23 @@ MHD_start_daemon_va (unsigned int options, | |||
1274 | unsigned int leftover_conns = retVal->max_connections | 1275 | unsigned int leftover_conns = retVal->max_connections |
1275 | % retVal->worker_pool_size; | 1276 | % retVal->worker_pool_size; |
1276 | 1277 | ||
1278 | i = 0; /* we need this in case malloc fails */ | ||
1277 | /* Allocate memory for pooled objects */ | 1279 | /* Allocate memory for pooled objects */ |
1278 | retVal->worker_pool = malloc (sizeof (*retVal->worker_pool) | 1280 | retVal->worker_pool = malloc (sizeof (struct MHD_Daemon) |
1279 | * retVal->worker_pool_size); | 1281 | * retVal->worker_pool_size); |
1282 | if (NULL == retVal->worker_pool) | ||
1283 | goto thread_failed; | ||
1280 | 1284 | ||
1281 | /* Start the workers in the pool */ | 1285 | /* Start the workers in the pool */ |
1282 | for (i = 0; i < retVal->worker_pool_size; ++i) | 1286 | for (i = 0; i < retVal->worker_pool_size; ++i) |
1283 | { | 1287 | { |
1284 | /* Create copy of the Daemon object for each worker */ | 1288 | /* Create copy of the Daemon object for each worker */ |
1285 | struct MHD_Daemon *d = (struct MHD_Daemon*) malloc (sizeof (*d)); | 1289 | struct MHD_Daemon *d = &retVal->worker_pool[i]; |
1286 | if (!d) | 1290 | memcpy (d, retVal, sizeof (struct MHD_Daemon)); |
1287 | { | ||
1288 | #if HAVE_MESSAGES | ||
1289 | MHD_DLOG (retVal, | ||
1290 | "Failed to copy daemon object: %d\n", STRERROR (errno)); | ||
1291 | #endif | ||
1292 | goto thread_failed; | ||
1293 | } | ||
1294 | memcpy (d, retVal, sizeof (*d)); | ||
1295 | 1291 | ||
1296 | /* Adjust pooling params for worker daemons; note that memcpy() | 1292 | /* Adjust pooling params for worker daemons; note that memcpy() |
1297 | * has already copied MHD_USE_SELECT_INTERNALLY thread model into | 1293 | has already copied MHD_USE_SELECT_INTERNALLY thread model into |
1298 | * the worker threads. */ | 1294 | the worker threads. */ |
1299 | d->master = retVal; | 1295 | d->master = retVal; |
1300 | d->worker_pool_size = 0; | 1296 | d->worker_pool_size = 0; |
1301 | d->worker_pool = NULL; | 1297 | d->worker_pool = NULL; |
@@ -1316,36 +1312,34 @@ MHD_start_daemon_va (unsigned int options, | |||
1316 | #endif | 1312 | #endif |
1317 | /* Free memory for this worker; cleanup below handles | 1313 | /* Free memory for this worker; cleanup below handles |
1318 | * all previously-created workers. */ | 1314 | * all previously-created workers. */ |
1319 | free (d); | ||
1320 | goto thread_failed; | 1315 | goto thread_failed; |
1321 | } | 1316 | } |
1322 | 1317 | } | |
1323 | retVal->worker_pool[i] = d; | 1318 | } |
1324 | continue; | 1319 | return retVal; |
1325 | 1320 | ||
1326 | thread_failed: | 1321 | thread_failed: |
1327 | /* If no worker threads created, then shut down normally. Calling | 1322 | /* If no worker threads created, then shut down normally. Calling |
1328 | * MHD_stop_daemon (as we do below) doesn't work here since it | 1323 | MHD_stop_daemon (as we do below) doesn't work here since it |
1329 | * assumes a 0-sized thread pool means we had been in the default | 1324 | assumes a 0-sized thread pool means we had been in the default |
1330 | * MHD_USE_SELECT_INTERNALLY mode. */ | 1325 | MHD_USE_SELECT_INTERNALLY mode. */ |
1331 | if (i == 0) | 1326 | if (i == 0) |
1332 | { | 1327 | { |
1333 | CLOSE (socket_fd); | 1328 | CLOSE (socket_fd); |
1334 | pthread_mutex_destroy (&retVal->per_ip_connection_mutex); | 1329 | pthread_mutex_destroy (&retVal->per_ip_connection_mutex); |
1335 | free (retVal); | 1330 | if (NULL != retVal->worker_pool) |
1336 | return NULL; | 1331 | free (retVal->worker_pool); |
1337 | } | 1332 | free (retVal); |
1338 | 1333 | return NULL; | |
1339 | /* Shutdown worker threads we've already created. Pretend | ||
1340 | * as though we had fully initialized our daemon, but | ||
1341 | * with a smaller number of threads than had been | ||
1342 | * requested. */ | ||
1343 | retVal->worker_pool_size = i - 1; | ||
1344 | MHD_stop_daemon (retVal); | ||
1345 | return NULL; | ||
1346 | } | ||
1347 | } | 1334 | } |
1348 | return retVal; | 1335 | |
1336 | /* Shutdown worker threads we've already created. Pretend | ||
1337 | as though we had fully initialized our daemon, but | ||
1338 | with a smaller number of threads than had been | ||
1339 | requested. */ | ||
1340 | retVal->worker_pool_size = i - 1; | ||
1341 | MHD_stop_daemon (retVal); | ||
1342 | return NULL; | ||
1349 | } | 1343 | } |
1350 | 1344 | ||
1351 | /** | 1345 | /** |
@@ -1389,8 +1383,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
1389 | /* Prepare workers for shutdown */ | 1383 | /* Prepare workers for shutdown */ |
1390 | for (i = 0; i < daemon->worker_pool_size; ++i) | 1384 | for (i = 0; i < daemon->worker_pool_size; ++i) |
1391 | { | 1385 | { |
1392 | daemon->worker_pool[i]->shutdown = MHD_YES; | 1386 | daemon->worker_pool[i].shutdown = MHD_YES; |
1393 | daemon->worker_pool[i]->socket_fd = -1; | 1387 | daemon->worker_pool[i].socket_fd = -1; |
1394 | } | 1388 | } |
1395 | 1389 | ||
1396 | #if DEBUG_CLOSE | 1390 | #if DEBUG_CLOSE |
@@ -1402,12 +1396,11 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
1402 | 1396 | ||
1403 | /* Signal workers to stop and clean them up */ | 1397 | /* Signal workers to stop and clean them up */ |
1404 | for (i = 0; i < daemon->worker_pool_size; ++i) | 1398 | for (i = 0; i < daemon->worker_pool_size; ++i) |
1405 | pthread_kill (daemon->worker_pool[i]->pid, SIGALRM); | 1399 | pthread_kill (daemon->worker_pool[i].pid, SIGALRM); |
1406 | for (i = 0; i < daemon->worker_pool_size; ++i) | 1400 | for (i = 0; i < daemon->worker_pool_size; ++i) |
1407 | { | 1401 | { |
1408 | pthread_join (daemon->worker_pool[i]->pid, &unused); | 1402 | pthread_join (daemon->worker_pool[i].pid, &unused); |
1409 | MHD_close_connections (daemon->worker_pool[i]); | 1403 | MHD_close_connections (&daemon->worker_pool[i]); |
1410 | free (daemon->worker_pool[i]); | ||
1411 | } | 1404 | } |
1412 | free (daemon->worker_pool); | 1405 | free (daemon->worker_pool); |
1413 | 1406 | ||
diff --git a/src/daemon/internal.h b/src/daemon/internal.h index fcc1fd57..7b4a0e72 100644 --- a/src/daemon/internal.h +++ b/src/daemon/internal.h | |||
@@ -779,7 +779,7 @@ struct MHD_Daemon | |||
779 | /** | 779 | /** |
780 | * Worker daemons (one per thread) | 780 | * Worker daemons (one per thread) |
781 | */ | 781 | */ |
782 | struct MHD_Daemon **worker_pool; | 782 | struct MHD_Daemon *worker_pool; |
783 | 783 | ||
784 | /** | 784 | /** |
785 | * Number of worker daemons | 785 | * Number of worker daemons |
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index 34ce1d98..9f40e9b1 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h | |||
@@ -439,7 +439,7 @@ enum MHD_OPTION | |||
439 | * (MHD_start_daemon returns NULL for an unsupported thread | 439 | * (MHD_start_daemon returns NULL for an unsupported thread |
440 | * model). | 440 | * model). |
441 | */ | 441 | */ |
442 | MHD_OPTION_THREAD_POOL_SIZE = 14, | 442 | MHD_OPTION_THREAD_POOL_SIZE = 14 |
443 | }; | 443 | }; |
444 | 444 | ||
445 | /** | 445 | /** |
diff --git a/src/testcurl/daemontest_iplimit.c b/src/testcurl/daemontest_iplimit.c index f9b5aba5..93e6b06c 100644 --- a/src/testcurl/daemontest_iplimit.c +++ b/src/testcurl/daemontest_iplimit.c | |||
@@ -137,8 +137,8 @@ testMultithreadedGet () | |||
137 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); | 137 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
138 | 138 | ||
139 | errornum = curl_easy_perform (c); | 139 | errornum = curl_easy_perform (c); |
140 | if (CURLE_OK != errornum && i < 2 | 140 | if ( ( (CURLE_OK != errornum) && (i < 2) ) || |
141 | || CURLE_OK == errornum && i == 2) | 141 | ( (CURLE_OK == errornum) && (i == 2) ) ) |
142 | { | 142 | { |
143 | int j; | 143 | int j; |
144 | 144 | ||
@@ -235,8 +235,8 @@ testMultithreadedPoolGet () | |||
235 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); | 235 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
236 | 236 | ||
237 | errornum = curl_easy_perform (c); | 237 | errornum = curl_easy_perform (c); |
238 | if (CURLE_OK != errornum && i < 2 | 238 | if ( ( (CURLE_OK != errornum) && (i < 2) ) || |
239 | || CURLE_OK == errornum && i == 2) | 239 | ( (CURLE_OK == errornum) && (i == 2) ) ) |
240 | { | 240 | { |
241 | int j; | 241 | int j; |
242 | 242 | ||
diff --git a/src/testcurl/https/mhds_multi_daemon_test.c b/src/testcurl/https/mhds_multi_daemon_test.c index 910989ab..7b9d0fe6 100644 --- a/src/testcurl/https/mhds_multi_daemon_test.c +++ b/src/testcurl/https/mhds_multi_daemon_test.c | |||
@@ -72,6 +72,7 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version, | |||
72 | { | 72 | { |
73 | fprintf (stderr, "Error: failed to read test file. %s\n", | 73 | fprintf (stderr, "Error: failed to read test file. %s\n", |
74 | strerror (errno)); | 74 | strerror (errno)); |
75 | free (mem_test_file_local); | ||
75 | return -1; | 76 | return -1; |
76 | } | 77 | } |
77 | cbc.size = len; | 78 | cbc.size = len; |
@@ -79,6 +80,8 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version, | |||
79 | 80 | ||
80 | if (gen_test_file_url (url, port)) | 81 | if (gen_test_file_url (url, port)) |
81 | { | 82 | { |
83 | free (mem_test_file_local); | ||
84 | free (cbc.buf); | ||
82 | return -1; | 85 | return -1; |
83 | } | 86 | } |
84 | 87 | ||
@@ -112,6 +115,8 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version, | |||
112 | fprintf (stderr, "curl_easy_perform failed: `%s'\n", | 115 | fprintf (stderr, "curl_easy_perform failed: `%s'\n", |
113 | curl_easy_strerror (errornum)); | 116 | curl_easy_strerror (errornum)); |
114 | curl_easy_cleanup (c); | 117 | curl_easy_cleanup (c); |
118 | free (mem_test_file_local); | ||
119 | free (cbc.buf); | ||
115 | return errornum; | 120 | return errornum; |
116 | } | 121 | } |
117 | 122 | ||
diff --git a/src/testcurl/https/tls_extension_test.c b/src/testcurl/https/tls_extension_test.c index 17745529..31b57e55 100644 --- a/src/testcurl/https/tls_extension_test.c +++ b/src/testcurl/https/tls_extension_test.c | |||
@@ -69,6 +69,7 @@ test_hello_extension (MHD_gtls_session_t session, extensions_t exten_t, | |||
69 | unsigned char comp[] = { 0x01, 0x00 }; | 69 | unsigned char comp[] = { 0x01, 0x00 }; |
70 | struct CBC cbc; | 70 | struct CBC cbc; |
71 | 71 | ||
72 | sd = -1; | ||
72 | memset (&cbc, 0, sizeof (struct CBC)); | 73 | memset (&cbc, 0, sizeof (struct CBC)); |
73 | if (NULL == (cbc.buf = malloc (sizeof (char) * 256))) | 74 | if (NULL == (cbc.buf = malloc (sizeof (char) * 256))) |
74 | { | 75 | { |
@@ -79,6 +80,12 @@ test_hello_extension (MHD_gtls_session_t session, extensions_t exten_t, | |||
79 | cbc.size = 256; | 80 | cbc.size = 256; |
80 | 81 | ||
81 | sd = socket (AF_INET, SOCK_STREAM, 0); | 82 | sd = socket (AF_INET, SOCK_STREAM, 0); |
83 | if (sd == -1) | ||
84 | { | ||
85 | fprintf(stderr, "Failed to create socket: %s\n", strerror(errno)); | ||
86 | free (cbc.buf); | ||
87 | return -1; | ||
88 | } | ||
82 | memset (&sa, '\0', sizeof (struct sockaddr_in)); | 89 | memset (&sa, '\0', sizeof (struct sockaddr_in)); |
83 | sa.sin_family = AF_INET; | 90 | sa.sin_family = AF_INET; |
84 | sa.sin_port = htons (DEAMON_TEST_PORT); | 91 | sa.sin_port = htons (DEAMON_TEST_PORT); |
@@ -186,7 +193,8 @@ test_hello_extension (MHD_gtls_session_t session, extensions_t exten_t, | |||
186 | } | 193 | } |
187 | 194 | ||
188 | cleanup: | 195 | cleanup: |
189 | close (sd); | 196 | if (sd != -1) |
197 | close (sd); | ||
190 | MHD_gnutls_free (cbc.buf); | 198 | MHD_gnutls_free (cbc.buf); |
191 | return ret; | 199 | return ret; |
192 | } | 200 | } |
diff --git a/src/testcurl/https/tls_test_common.c b/src/testcurl/https/tls_test_common.c index a960b086..97d7a4ba 100644 --- a/src/testcurl/https/tls_test_common.c +++ b/src/testcurl/https/tls_test_common.c | |||
@@ -189,7 +189,7 @@ gen_test_file_url (char *url, int port) | |||
189 | if (NULL == (doc_path = malloc (doc_path_len))) | 189 | if (NULL == (doc_path = malloc (doc_path_len))) |
190 | { | 190 | { |
191 | fprintf (stderr, MHD_E_MEM); | 191 | fprintf (stderr, MHD_E_MEM); |
192 | ret = -1; | 192 | return -1; |
193 | } | 193 | } |
194 | if (getcwd (doc_path, doc_path_len) == NULL) | 194 | if (getcwd (doc_path, doc_path_len) == NULL) |
195 | { | 195 | { |
@@ -220,9 +220,14 @@ test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version) | |||
220 | /* used to memcmp local copy & deamon supplied copy */ | 220 | /* used to memcmp local copy & deamon supplied copy */ |
221 | unsigned char *mem_test_file_local; | 221 | unsigned char *mem_test_file_local; |
222 | 222 | ||
223 | stat (TEST_FILE_NAME, &statb); | 223 | if (0 != stat (TEST_FILE_NAME, &statb)) |
224 | { | ||
225 | fprintf (stderr, "Failed to stat `%s': %s\n", | ||
226 | TEST_FILE_NAME, strerror(errno)); | ||
227 | return -1; | ||
228 | } | ||
224 | len = statb.st_size; | 229 | len = statb.st_size; |
225 | 230 | cbc.buf = NULL; | |
226 | if (NULL == (mem_test_file_local = malloc (len))) | 231 | if (NULL == (mem_test_file_local = malloc (len))) |
227 | { | 232 | { |
228 | fprintf (stderr, MHD_E_MEM); | 233 | fprintf (stderr, MHD_E_MEM); |
@@ -269,7 +274,8 @@ test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version) | |||
269 | 274 | ||
270 | cleanup: | 275 | cleanup: |
271 | free (mem_test_file_local); | 276 | free (mem_test_file_local); |
272 | free (cbc.buf); | 277 | if (cbc.buf != NULL) |
278 | free (cbc.buf); | ||
273 | return ret; | 279 | return ret; |
274 | } | 280 | } |
275 | 281 | ||
@@ -341,7 +347,7 @@ setup_session (MHD_gtls_session_t * session, | |||
341 | MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t * xcred) | 347 | MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t * xcred) |
342 | { | 348 | { |
343 | int ret; | 349 | int ret; |
344 | const char **err_pos; | 350 | const char *err_pos; |
345 | 351 | ||
346 | MHD__gnutls_certificate_allocate_credentials (xcred); | 352 | MHD__gnutls_certificate_allocate_credentials (xcred); |
347 | 353 | ||
@@ -353,7 +359,7 @@ setup_session (MHD_gtls_session_t * session, | |||
353 | GNUTLS_X509_FMT_PEM); | 359 | GNUTLS_X509_FMT_PEM); |
354 | 360 | ||
355 | MHD__gnutls_init (session, GNUTLS_CLIENT); | 361 | MHD__gnutls_init (session, GNUTLS_CLIENT); |
356 | ret = MHD__gnutls_priority_set_direct (*session, "NORMAL", err_pos); | 362 | ret = MHD__gnutls_priority_set_direct (*session, "NORMAL", &err_pos); |
357 | if (ret < 0) | 363 | if (ret < 0) |
358 | { | 364 | { |
359 | return -1; | 365 | return -1; |