commit e9128f7887291e9239e380d250960580463d157b
parent d2630b7e6970c4a67c4e914e4f426f7da0f51c29
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 17 Mar 2009 07:34:32 +0000
various bugfixes and docu updates
Diffstat:
8 files changed, 74 insertions(+), 59 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,5 +1,8 @@
+Tue Mar 17 01:19:50 MDT 2009
+ Added support for thread-pools. -CG/RA
+
Mon Mar 2 23:44:08 MST 2009
- Fixd problem with 64-bit upload and download sizes and
+ Fixed problem with 64-bit upload and download sizes and
"-1" being used to indicate "unknown" by introducing
new 64-bit constant "MHD_SIZE_UNKNOWN". -CG/DC
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
@@ -1138,6 +1138,7 @@ MHD_start_daemon_va (unsigned int options,
FPRINTF (stderr,
"MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n");
#endif
+ free (retVal);
return NULL;
}
@@ -1252,7 +1253,7 @@ MHD_start_daemon_va (unsigned int options,
if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
((0 != (options & MHD_USE_SELECT_INTERNALLY))
&& (0 == retVal->worker_pool_size)))
- && (0 !=
+ && (0 !=
pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal)))
{
#if HAVE_MESSAGES
@@ -1274,28 +1275,23 @@ MHD_start_daemon_va (unsigned int options,
unsigned int leftover_conns = retVal->max_connections
% retVal->worker_pool_size;
+ i = 0; /* we need this in case malloc fails */
/* Allocate memory for pooled objects */
- retVal->worker_pool = malloc (sizeof (*retVal->worker_pool)
+ retVal->worker_pool = malloc (sizeof (struct MHD_Daemon)
* retVal->worker_pool_size);
+ if (NULL == retVal->worker_pool)
+ goto thread_failed;
/* Start the workers in the pool */
for (i = 0; i < retVal->worker_pool_size; ++i)
{
/* Create copy of the Daemon object for each worker */
- struct MHD_Daemon *d = (struct MHD_Daemon*) malloc (sizeof (*d));
- if (!d)
- {
-#if HAVE_MESSAGES
- MHD_DLOG (retVal,
- "Failed to copy daemon object: %d\n", STRERROR (errno));
-#endif
- goto thread_failed;
- }
- memcpy (d, retVal, sizeof (*d));
+ struct MHD_Daemon *d = &retVal->worker_pool[i];
+ memcpy (d, retVal, sizeof (struct MHD_Daemon));
/* Adjust pooling params for worker daemons; note that memcpy()
- * has already copied MHD_USE_SELECT_INTERNALLY thread model into
- * the worker threads. */
+ has already copied MHD_USE_SELECT_INTERNALLY thread model into
+ the worker threads. */
d->master = retVal;
d->worker_pool_size = 0;
d->worker_pool = NULL;
@@ -1316,36 +1312,34 @@ MHD_start_daemon_va (unsigned int options,
#endif
/* Free memory for this worker; cleanup below handles
* all previously-created workers. */
- free (d);
goto thread_failed;
}
-
- retVal->worker_pool[i] = d;
- continue;
+ }
+ }
+ return retVal;
thread_failed:
- /* If no worker threads created, then shut down normally. Calling
- * MHD_stop_daemon (as we do below) doesn't work here since it
- * assumes a 0-sized thread pool means we had been in the default
- * MHD_USE_SELECT_INTERNALLY mode. */
- if (i == 0)
- {
- CLOSE (socket_fd);
- pthread_mutex_destroy (&retVal->per_ip_connection_mutex);
- free (retVal);
- return NULL;
- }
-
- /* Shutdown worker threads we've already created. Pretend
- * as though we had fully initialized our daemon, but
- * with a smaller number of threads than had been
- * requested. */
- retVal->worker_pool_size = i - 1;
- MHD_stop_daemon (retVal);
- return NULL;
- }
+ /* If no worker threads created, then shut down normally. Calling
+ MHD_stop_daemon (as we do below) doesn't work here since it
+ assumes a 0-sized thread pool means we had been in the default
+ MHD_USE_SELECT_INTERNALLY mode. */
+ if (i == 0)
+ {
+ CLOSE (socket_fd);
+ pthread_mutex_destroy (&retVal->per_ip_connection_mutex);
+ if (NULL != retVal->worker_pool)
+ free (retVal->worker_pool);
+ free (retVal);
+ return NULL;
}
- return retVal;
+
+ /* Shutdown worker threads we've already created. Pretend
+ as though we had fully initialized our daemon, but
+ with a smaller number of threads than had been
+ requested. */
+ retVal->worker_pool_size = i - 1;
+ MHD_stop_daemon (retVal);
+ return NULL;
}
/**
@@ -1389,8 +1383,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
/* Prepare workers for shutdown */
for (i = 0; i < daemon->worker_pool_size; ++i)
{
- daemon->worker_pool[i]->shutdown = MHD_YES;
- daemon->worker_pool[i]->socket_fd = -1;
+ daemon->worker_pool[i].shutdown = MHD_YES;
+ daemon->worker_pool[i].socket_fd = -1;
}
#if DEBUG_CLOSE
@@ -1402,12 +1396,11 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
/* Signal workers to stop and clean them up */
for (i = 0; i < daemon->worker_pool_size; ++i)
- pthread_kill (daemon->worker_pool[i]->pid, SIGALRM);
+ pthread_kill (daemon->worker_pool[i].pid, SIGALRM);
for (i = 0; i < daemon->worker_pool_size; ++i)
{
- pthread_join (daemon->worker_pool[i]->pid, &unused);
- MHD_close_connections (daemon->worker_pool[i]);
- free (daemon->worker_pool[i]);
+ pthread_join (daemon->worker_pool[i].pid, &unused);
+ MHD_close_connections (&daemon->worker_pool[i]);
}
free (daemon->worker_pool);
diff --git a/src/daemon/internal.h b/src/daemon/internal.h
@@ -779,7 +779,7 @@ struct MHD_Daemon
/**
* Worker daemons (one per thread)
*/
- struct MHD_Daemon **worker_pool;
+ struct MHD_Daemon *worker_pool;
/**
* Number of worker daemons
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
@@ -439,7 +439,7 @@ enum MHD_OPTION
* (MHD_start_daemon returns NULL for an unsupported thread
* model).
*/
- MHD_OPTION_THREAD_POOL_SIZE = 14,
+ MHD_OPTION_THREAD_POOL_SIZE = 14
};
/**
diff --git a/src/testcurl/daemontest_iplimit.c b/src/testcurl/daemontest_iplimit.c
@@ -137,8 +137,8 @@ testMultithreadedGet ()
curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
errornum = curl_easy_perform (c);
- if (CURLE_OK != errornum && i < 2
- || CURLE_OK == errornum && i == 2)
+ if ( ( (CURLE_OK != errornum) && (i < 2) ) ||
+ ( (CURLE_OK == errornum) && (i == 2) ) )
{
int j;
@@ -235,8 +235,8 @@ testMultithreadedPoolGet ()
curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
errornum = curl_easy_perform (c);
- if (CURLE_OK != errornum && i < 2
- || CURLE_OK == errornum && i == 2)
+ if ( ( (CURLE_OK != errornum) && (i < 2) ) ||
+ ( (CURLE_OK == errornum) && (i == 2) ) )
{
int j;
diff --git 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,
{
fprintf (stderr, "Error: failed to read test file. %s\n",
strerror (errno));
+ free (mem_test_file_local);
return -1;
}
cbc.size = len;
@@ -79,6 +80,8 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version,
if (gen_test_file_url (url, port))
{
+ free (mem_test_file_local);
+ free (cbc.buf);
return -1;
}
@@ -112,6 +115,8 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version,
fprintf (stderr, "curl_easy_perform failed: `%s'\n",
curl_easy_strerror (errornum));
curl_easy_cleanup (c);
+ free (mem_test_file_local);
+ free (cbc.buf);
return errornum;
}
diff --git 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,
unsigned char comp[] = { 0x01, 0x00 };
struct CBC cbc;
+ sd = -1;
memset (&cbc, 0, sizeof (struct CBC));
if (NULL == (cbc.buf = malloc (sizeof (char) * 256)))
{
@@ -79,6 +80,12 @@ test_hello_extension (MHD_gtls_session_t session, extensions_t exten_t,
cbc.size = 256;
sd = socket (AF_INET, SOCK_STREAM, 0);
+ if (sd == -1)
+ {
+ fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
+ free (cbc.buf);
+ return -1;
+ }
memset (&sa, '\0', sizeof (struct sockaddr_in));
sa.sin_family = AF_INET;
sa.sin_port = htons (DEAMON_TEST_PORT);
@@ -186,7 +193,8 @@ test_hello_extension (MHD_gtls_session_t session, extensions_t exten_t,
}
cleanup:
- close (sd);
+ if (sd != -1)
+ close (sd);
MHD_gnutls_free (cbc.buf);
return ret;
}
diff --git 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)
if (NULL == (doc_path = malloc (doc_path_len)))
{
fprintf (stderr, MHD_E_MEM);
- ret = -1;
+ return -1;
}
if (getcwd (doc_path, doc_path_len) == NULL)
{
@@ -220,9 +220,14 @@ test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version)
/* used to memcmp local copy & deamon supplied copy */
unsigned char *mem_test_file_local;
- stat (TEST_FILE_NAME, &statb);
+ if (0 != stat (TEST_FILE_NAME, &statb))
+ {
+ fprintf (stderr, "Failed to stat `%s': %s\n",
+ TEST_FILE_NAME, strerror(errno));
+ return -1;
+ }
len = statb.st_size;
-
+ cbc.buf = NULL;
if (NULL == (mem_test_file_local = malloc (len)))
{
fprintf (stderr, MHD_E_MEM);
@@ -269,7 +274,8 @@ test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version)
cleanup:
free (mem_test_file_local);
- free (cbc.buf);
+ if (cbc.buf != NULL)
+ free (cbc.buf);
return ret;
}
@@ -341,7 +347,7 @@ setup_session (MHD_gtls_session_t * session,
MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t * xcred)
{
int ret;
- const char **err_pos;
+ const char *err_pos;
MHD__gnutls_certificate_allocate_credentials (xcred);
@@ -353,7 +359,7 @@ setup_session (MHD_gtls_session_t * session,
GNUTLS_X509_FMT_PEM);
MHD__gnutls_init (session, GNUTLS_CLIENT);
- ret = MHD__gnutls_priority_set_direct (*session, "NORMAL", err_pos);
+ ret = MHD__gnutls_priority_set_direct (*session, "NORMAL", &err_pos);
if (ret < 0)
{
return -1;