[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r8336 - in libmicrohttpd/src: daemon include testcurl
From: |
gnunet |
Subject: |
[GNUnet-SVN] r8336 - in libmicrohttpd/src: daemon include testcurl |
Date: |
Tue, 17 Mar 2009 00:59:31 -0600 |
Author: grothoff
Date: 2009-03-17 00:59:31 -0600 (Tue, 17 Mar 2009)
New Revision: 8336
Modified:
libmicrohttpd/src/daemon/daemon.c
libmicrohttpd/src/daemon/internal.h
libmicrohttpd/src/include/microhttpd.h
libmicrohttpd/src/testcurl/daemontest_get.c
libmicrohttpd/src/testcurl/daemontest_get_chunked.c
libmicrohttpd/src/testcurl/daemontest_iplimit.c
libmicrohttpd/src/testcurl/daemontest_large_put.c
libmicrohttpd/src/testcurl/daemontest_post.c
libmicrohttpd/src/testcurl/daemontest_post_loop.c
libmicrohttpd/src/testcurl/daemontest_postform.c
libmicrohttpd/src/testcurl/daemontest_process_headers.c
libmicrohttpd/src/testcurl/daemontest_put.c
libmicrohttpd/src/testcurl/daemontest_put_chunked.c
Log:
adding thread pool functionality -- code by Richard Alimi
Modified: libmicrohttpd/src/daemon/daemon.c
===================================================================
--- libmicrohttpd/src/daemon/daemon.c 2009-03-17 06:57:36 UTC (rev 8335)
+++ libmicrohttpd/src/daemon/daemon.c 2009-03-17 06:59:31 UTC (rev 8336)
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- (C) 2007, 2008 Daniel Pittman and Christian Grothoff
+ (C) 2007, 2008, 2009 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -187,8 +187,8 @@
if (daemon->per_ip_connection_limit == 0)
return MHD_YES;
- key = (struct MHD_IPCount*) malloc (sizeof(*key));
- if (!key)
+ key = malloc (sizeof(*key));
+ if (NULL == key)
return MHD_NO;
/* Initialize key */
@@ -625,7 +625,7 @@
#endif
#endif
connection = malloc (sizeof (struct MHD_Connection));
- if (connection == NULL)
+ if (NULL == connection)
{
#if HAVE_MESSAGES
MHD_DLOG (daemon, "Error allocating memory: %s\n", STRERROR (errno));
@@ -1017,6 +1017,7 @@
const struct sockaddr *servaddr = NULL;
socklen_t addrlen;
enum MHD_OPTION opt;
+ unsigned int i;
if ((port == 0) || (dh == NULL))
return NULL;
@@ -1080,6 +1081,9 @@
va_arg (ap, LogCallback);
retVal->uri_log_callback_cls = va_arg (ap, void *);
break;
+ case MHD_OPTION_THREAD_POOL_SIZE:
+ retVal->worker_pool_size = va_arg (ap, unsigned int);
+ break;
#if HTTPS_SUPPORT
case MHD_OPTION_PROTOCOL_VERSION:
_set_priority (&retVal->priority_cache->protocol,
@@ -1126,6 +1130,17 @@
}
}
+ /* Thread pooling currently works only with internal select thread model */
+ if ((0 == (options & MHD_USE_SELECT_INTERNALLY))
+ && (retVal->worker_pool_size > 0))
+ {
+#if HAVE_MESSAGES
+ FPRINTF (stderr,
+ "MHD thread pooling only works with
MHD_USE_SELECT_INTERNALLY\n");
+#endif
+ return NULL;
+ }
+
if ((options & MHD_USE_IPv6) != 0)
#if HAVE_INET6
socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0);
@@ -1235,7 +1250,8 @@
}
#endif
if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
- (0 != (options & MHD_USE_SELECT_INTERNALLY)))
+ ((0 != (options & MHD_USE_SELECT_INTERNALLY))
+ && (0 == retVal->worker_pool_size)))
&& (0 !=
pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal)))
{
@@ -1248,6 +1264,87 @@
CLOSE (socket_fd);
return NULL;
}
+ else if (retVal->worker_pool_size > 0)
+ {
+ /* Coarse-grained count of connections per thread (note error
+ * due to integer division). Also keep track of how many
+ * connections are leftover after an equal split. */
+ unsigned int conns_per_thread = retVal->max_connections
+ / retVal->worker_pool_size;
+ unsigned int leftover_conns = retVal->max_connections
+ % retVal->worker_pool_size;
+
+ /* Allocate memory for pooled objects */
+ retVal->worker_pool = malloc (sizeof (*retVal->worker_pool)
+ * retVal->worker_pool_size);
+
+ /* 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));
+
+ /* Adjust pooling params for worker daemons; note that memcpy()
+ * 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;
+
+ /* Divide available connections evenly amongst the threads.
+ * Thread indexes in [0, leftover_conns) each get one of the
+ * leftover connections. */
+ d->max_connections = conns_per_thread;
+ if (i < leftover_conns)
+ ++d->max_connections;
+
+ /* Spawn the worker thread */
+ if (0 != pthread_create (&d->pid, NULL, &MHD_select_thread, d))
+ {
+#if HAVE_MESSAGES
+ MHD_DLOG (retVal,
+ "Failed to create pool thread: %d\n", STRERROR
(errno));
+#endif
+ /* Free memory for this worker; cleanup below handles
+ * all previously-created workers. */
+ free (d);
+ goto thread_failed;
+ }
+
+ retVal->worker_pool[i] = d;
+ continue;
+
+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;
+ }
+ }
return retVal;
}
@@ -1281,20 +1378,42 @@
{
void *unused;
int fd;
+ unsigned int i;
if (daemon == NULL)
return;
daemon->shutdown = MHD_YES;
fd = daemon->socket_fd;
daemon->socket_fd = -1;
+
+ /* 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;
+ }
+
#if DEBUG_CLOSE
#if HAVE_MESSAGES
MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n");
#endif
#endif
CLOSE (fd);
+
+ /* 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);
+ 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]);
+ }
+ free (daemon->worker_pool);
+
if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
- (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)))
+ ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
+ && (0 == daemon->worker_pool_size)))
{
pthread_kill (daemon->pid, SIGALRM);
pthread_join (daemon->pid, &unused);
Modified: libmicrohttpd/src/daemon/internal.h
===================================================================
--- libmicrohttpd/src/daemon/internal.h 2009-03-17 06:57:36 UTC (rev 8335)
+++ libmicrohttpd/src/daemon/internal.h 2009-03-17 06:59:31 UTC (rev 8336)
@@ -775,6 +775,16 @@
* Pointer to master daemon (NULL if this is the master)
*/
struct MHD_Daemon *master;
+
+ /**
+ * Worker daemons (one per thread)
+ */
+ struct MHD_Daemon **worker_pool;
+
+ /**
+ * Number of worker daemons
+ */
+ unsigned int worker_pool_size;
};
Modified: libmicrohttpd/src/include/microhttpd.h
===================================================================
--- libmicrohttpd/src/include/microhttpd.h 2009-03-17 06:57:36 UTC (rev
8335)
+++ libmicrohttpd/src/include/microhttpd.h 2009-03-17 06:59:31 UTC (rev
8336)
@@ -429,8 +429,17 @@
* if it was compiled without the "--enable-messages"
* flag being set.
*/
- MHD_OPTION_EXTERNAL_LOGGER = 13
+ MHD_OPTION_EXTERNAL_LOGGER = 13,
+ /**
+ * Number (unsigned int) of threads in thread pool. Enable
+ * thread pooling by setting this value to to something
+ * greater than 1. Currently, thread model must be
+ * MHD_USE_SELECT_INTERNALLY if thread pooling is enabled
+ * (MHD_start_daemon returns NULL for an unsupported thread
+ * model).
+ */
+ MHD_OPTION_THREAD_POOL_SIZE = 14,
};
/**
Modified: libmicrohttpd/src/testcurl/daemontest_get.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_get.c 2009-03-17 06:57:36 UTC (rev
8335)
+++ libmicrohttpd/src/testcurl/daemontest_get.c 2009-03-17 06:59:31 UTC (rev
8336)
@@ -188,7 +188,56 @@
return 0;
}
+static int
+testMultithreadedPoolGet ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 1081, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ // NOTE: use of CONNECTTIMEOUT without also
+ // setting NOSIGNAL results in really weird
+ // crashes on my system!
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 64;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 128;
+ return 0;
+}
+
static int
testExternalGet ()
{
@@ -323,6 +372,7 @@
return 2;
errorCount += testInternalGet ();
errorCount += testMultithreadedGet ();
+ errorCount += testMultithreadedPoolGet ();
errorCount += testExternalGet ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
Modified: libmicrohttpd/src/testcurl/daemontest_get_chunked.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_get_chunked.c 2009-03-17 06:57:36 UTC
(rev 8335)
+++ libmicrohttpd/src/testcurl/daemontest_get_chunked.c 2009-03-17 06:59:31 UTC
(rev 8336)
@@ -227,7 +227,49 @@
return validate (cbc, 64);
}
+static int
+testMultithreadedPoolGet ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 1081, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ // NOTE: use of CONNECTTIMEOUT without also
+ // setting NOSIGNAL results in really weird
+ // crashes on my system!
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return validate (cbc, 64);
+}
+
static int
testExternalGet ()
{
@@ -354,6 +396,7 @@
return 2;
errorCount += testInternalGet ();
errorCount += testMultithreadedGet ();
+ errorCount += testMultithreadedPoolGet ();
errorCount += testExternalGet ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
Modified: libmicrohttpd/src/testcurl/daemontest_iplimit.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_iplimit.c 2009-03-17 06:57:36 UTC
(rev 8335)
+++ libmicrohttpd/src/testcurl/daemontest_iplimit.c 2009-03-17 06:59:31 UTC
(rev 8336)
@@ -90,6 +90,103 @@
}
static int
+testMultithreadedGet ()
+{
+ struct MHD_Daemon *d;
+ char buf[2048];
+ int k;
+
+ /* Test only valid for HTTP/1.1 (uses persistent connections) */
+ if (!oneone)
+ return 0;
+
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 1081, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+
+ for (k = 0; k < 3; ++k)
+ {
+ struct CBC cbc[3];
+ CURL *cenv[3];
+ int i;
+
+ for (i = 0; i < 3; ++i)
+ {
+ CURL *c;
+ CURLcode errornum;
+
+ cenv[i] = c = curl_easy_init ();
+ cbc[i].buf = buf;
+ cbc[i].size = 2048;
+ cbc[i].pos = 0;
+
+ curl_easy_setopt (c, CURLOPT_URL,
"http://localhost:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_FORBID_REUSE, 0L);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ // NOTE: use of CONNECTTIMEOUT without also
+ // setting NOSIGNAL results in really weird
+ // crashes on my system!
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+
+ errornum = curl_easy_perform (c);
+ if (CURLE_OK != errornum && i < 2
+ || CURLE_OK == errornum && i == 2)
+ {
+ int j;
+
+ /* First 2 should succeed */
+ if (i < 2)
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+
+ /* Last request should have failed */
+ else
+ fprintf (stderr,
+ "No error on IP address over limit\n");
+
+ for (j = 0; j < i; ++j)
+ curl_easy_cleanup (cenv[j]);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ }
+
+ /* Cleanup the environments */
+ for (i = 0; i < 3; ++i)
+ curl_easy_cleanup (cenv[i]);
+
+ sleep(2);
+
+ for (i = 0; i < 2; ++i)
+ {
+ if (cbc[i].pos != strlen ("/hello_world"))
+ {
+ MHD_stop_daemon (d);
+ return 64;
+ }
+ if (0 != strncmp ("/hello_world", cbc[i].buf, strlen
("/hello_world")))
+ {
+ MHD_stop_daemon (d);
+ return 128;
+ }
+ }
+
+
+ }
+ MHD_stop_daemon (d);
+ return 0;
+}
+
+static int
testMultithreadedPoolGet ()
{
struct MHD_Daemon *d;
@@ -103,6 +200,7 @@
d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
1081, NULL, NULL, &ahc_echo, "GET",
MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
+ MHD_OPTION_THREAD_POOL_SIZE, 4,
MHD_OPTION_END);
if (d == NULL)
return 16;
@@ -194,6 +292,7 @@
oneone = NULL != strstr (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
+ errorCount += testMultithreadedGet ();
errorCount += testMultithreadedPoolGet ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
Modified: libmicrohttpd/src/testcurl/daemontest_large_put.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_large_put.c 2009-03-17 06:57:36 UTC
(rev 8335)
+++ libmicrohttpd/src/testcurl/daemontest_large_put.c 2009-03-17 06:59:31 UTC
(rev 8336)
@@ -245,7 +245,66 @@
return 0;
}
+static int
+testMultithreadedPoolPut ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ struct CBC cbc;
+ unsigned int pos = 0;
+ int done_flag = 0;
+ CURLcode errornum;
+ char buf[2048];
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 1081,
+ NULL, NULL, &ahc_echo, &done_flag,
+ MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ // NOTE: use of CONNECTTIMEOUT without also
+ // setting NOSIGNAL results in really weird
+ // crashes on my system!
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ {
+ fprintf (stderr, "Got invalid response `%.*s'\n", cbc.pos, cbc.buf);
+ return 64;
+ }
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 128;
+ return 0;
+}
+
static int
testExternalPut ()
{
@@ -394,6 +453,7 @@
memset (put_buffer, 1, PUT_SIZE);
errorCount += testInternalPut ();
errorCount += testMultithreadedPut ();
+ errorCount += testMultithreadedPoolPut ();
errorCount += testExternalPut ();
free (put_buffer);
if (errorCount != 0)
Modified: libmicrohttpd/src/testcurl/daemontest_post.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_post.c 2009-03-17 06:57:36 UTC
(rev 8335)
+++ libmicrohttpd/src/testcurl/daemontest_post.c 2009-03-17 06:59:31 UTC
(rev 8336)
@@ -231,7 +231,59 @@
return 0;
}
+static int
+testMultithreadedPoolPost ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 1081, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
+ curl_easy_setopt (c, CURLOPT_POST, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ // NOTE: use of CONNECTTIMEOUT without also
+ // setting NOSIGNAL results in really weird
+ // crashes on my system!
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 64;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 128;
+ return 0;
+}
+
static int
testExternalPost ()
{
@@ -369,6 +421,7 @@
return 2;
errorCount += testInternalPost ();
errorCount += testMultithreadedPost ();
+ errorCount += testMultithreadedPoolPost ();
errorCount += testExternalPost ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
Modified: libmicrohttpd/src/testcurl/daemontest_post_loop.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_post_loop.c 2009-03-17 06:57:36 UTC
(rev 8335)
+++ libmicrohttpd/src/testcurl/daemontest_post_loop.c 2009-03-17 06:59:31 UTC
(rev 8336)
@@ -225,7 +225,71 @@
return 0;
}
+static int
+testMultithreadedPoolPost ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ int i;
+ char url[1024];
+ cbc.buf = buf;
+ cbc.size = 2048;
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 1081, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ for (i = 0; i < LOOPCOUNT; i++)
+ {
+ if (99 == i % 100)
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ cbc.pos = 0;
+ buf[0] = '\0';
+ sprintf (url, "http://localhost:1081/hw%d", i);
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
+ curl_easy_setopt (c, CURLOPT_POST, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ // NOTE: use of CONNECTTIMEOUT without also
+ // setting NOSIGNAL results in really weird
+ // crashes on my system!
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ if ((buf[0] != 'O') || (buf[1] != 'K'))
+ {
+ MHD_stop_daemon (d);
+ return 64;
+ }
+ }
+ MHD_stop_daemon (d);
+ if (LOOPCOUNT >= 99)
+ fprintf (stderr, "\n");
+ return 0;
+}
+
static int
testExternalPost ()
{
@@ -379,6 +443,7 @@
return 2;
errorCount += testInternalPost ();
errorCount += testMultithreadedPost ();
+ errorCount += testMultithreadedPoolPost ();
errorCount += testExternalPost ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
Modified: libmicrohttpd/src/testcurl/daemontest_postform.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_postform.c 2009-03-17 06:57:36 UTC
(rev 8335)
+++ libmicrohttpd/src/testcurl/daemontest_postform.c 2009-03-17 06:59:31 UTC
(rev 8336)
@@ -251,7 +251,61 @@
return 0;
}
+static int
+testMultithreadedPoolPost ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ struct curl_httppost *pd;
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 1081, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ pd = make_form ();
+ curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
+ // NOTE: use of CONNECTTIMEOUT without also
+ // setting NOSIGNAL results in really weird
+ // crashes on my system!
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ curl_formfree (pd);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ curl_formfree (pd);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 64;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 128;
+ return 0;
+}
+
static int
testExternalPost ()
{
@@ -394,6 +448,7 @@
return 2;
errorCount += testInternalPost ();
errorCount += testMultithreadedPost ();
+ errorCount += testMultithreadedPoolPost ();
errorCount += testExternalPost ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
Modified: libmicrohttpd/src/testcurl/daemontest_process_headers.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_process_headers.c 2009-03-17
06:57:36 UTC (rev 8335)
+++ libmicrohttpd/src/testcurl/daemontest_process_headers.c 2009-03-17
06:59:31 UTC (rev 8336)
@@ -235,7 +235,56 @@
return 0;
}
+static int
+testMultithreadedPoolGet ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 21080, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://localhost:21080/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 64;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 128;
+ return 0;
+}
+
static int
testExternalGet ()
{
@@ -370,6 +419,7 @@
return 2;
errorCount += testInternalGet ();
errorCount += testMultithreadedGet ();
+ errorCount += testMultithreadedPoolGet ();
errorCount += testExternalGet ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
Modified: libmicrohttpd/src/testcurl/daemontest_put.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_put.c 2009-03-17 06:57:36 UTC (rev
8335)
+++ libmicrohttpd/src/testcurl/daemontest_put.c 2009-03-17 06:59:31 UTC (rev
8336)
@@ -223,7 +223,65 @@
return 0;
}
+static int
+testMultithreadedPoolPut ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ unsigned int pos = 0;
+ int done_flag = 0;
+ CURLcode errornum;
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 1081,
+ NULL, NULL, &ahc_echo, &done_flag,
+ MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ // NOTE: use of CONNECTTIMEOUT without also
+ // setting NOSIGNAL results in really weird
+ // crashes on my system!
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 64;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 128;
+
+ return 0;
+}
+
+
static int
testExternalPut ()
{
@@ -365,6 +423,7 @@
return 2;
errorCount += testInternalPut ();
errorCount += testMultithreadedPut ();
+ errorCount += testMultithreadedPoolPut ();
errorCount += testExternalPut ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
Modified: libmicrohttpd/src/testcurl/daemontest_put_chunked.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_put_chunked.c 2009-03-17 06:57:36 UTC
(rev 8335)
+++ libmicrohttpd/src/testcurl/daemontest_put_chunked.c 2009-03-17 06:59:31 UTC
(rev 8336)
@@ -232,7 +232,65 @@
return 0;
}
+static int
+testMultithreadedPoolPut ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ unsigned int pos = 0;
+ int done_flag = 0;
+ CURLcode errornum;
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+ 11081,
+ NULL, NULL, &ahc_echo, &done_flag,
+ MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ /*
+ // by not giving the file size, we force chunking!
+ curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+ */
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ // NOTE: use of CONNECTTIMEOUT without also
+ // setting NOSIGNAL results in really weird
+ // crashes on my system!
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 64;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 128;
+
+ return 0;
+}
+
+
static int
testExternalPut ()
{
@@ -373,6 +431,7 @@
return 2;
errorCount += testInternalPut ();
errorCount += testMultithreadedPut ();
+ errorCount += testMultithreadedPoolPut ();
errorCount += testExternalPut ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r8336 - in libmicrohttpd/src: daemon include testcurl,
gnunet <=