libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 41be6325c89377b9a2d9aff1493c3d4fb62e0fb4
parent 7ef544c9bed6159c46be44a3d130e0de094a345f
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 21 Sep 2011 07:47:35 +0000

From: 
Will Bryant <will.bryant@gmail.com>
  To: 
libmicrohttpd development and user mailinglist <libmicrohttpd@gnu.org>
  Date: 
Today 03:01:54 AM
  Attachments: 
 0001-use-separate-ports-for-subsequent-tests-in-the-perf-.patch
   
So patch attached to use sequential port number assignments in those two perf test programs - with that and the earlier pipe shutdown patch, OS X passes all tests now.

OpenIndiana also passes all the perf tests, leaving just the SIGPIPE matter.  Incidentally, performance is terrible there.  I would be interested to know why - my OpenIndiana box has a modern Intel Q9505 and gets in the region of 35 requests/s in each perf test, whereas my aging Intel Core 2 Duo macbook gets 600-900 despite having half the cores.  Of course we only expect the non-concurrent test to use about 1 of the cores, but both that and the concurrent test actually use only about 1% of a single CPU.  This is puzzling as OpenIndiana has the very performant and scalable sunos/solaris-derived kernel and libc, so something odd is definitely going on.

Regarding the SIGPIPE, do you think a signal handler should be installed in all test programs, to implement the recommended behavior for applications, or only in those that need it?

I am sitting on the fence.  I think the argument for the latter would be that one would not normally expect SIGPIPE to occur during tests that do not test out error/abort behavior, but I don't think it would normally be harmful.

(I haven't implemented the configure script integration to set the HAVE_LISTEN_SHUTDOWN conditional define for Linux etc. - can you help there?  I have, for what it's worth, checked that Linux does also work using the pipe technique instead, so that seems well-portable.)

Cheers,
Will



Diffstat:
Msrc/testcurl/perf_get.c | 51++++++++++++++++++++++++++++++++-------------------
Msrc/testcurl/perf_get_concurrent.c | 46+++++++++++++++++++++++++---------------------
2 files changed, 57 insertions(+), 40 deletions(-)

diff --git a/src/testcurl/perf_get.c b/src/testcurl/perf_get.c @@ -171,7 +171,7 @@ ahc_echo (void *cls, static int -testInternalGet (int poll_flag) +testInternalGet (int port, int poll_flag) { struct MHD_Daemon *d; CURL *c; @@ -179,11 +179,14 @@ testInternalGet (int poll_flag) struct CBC cbc; CURLcode errornum; unsigned int i; + char url[64]; + + sprintf(url, "http://localhost:%d/hello_world", port); cbc.buf = buf; cbc.size = 2048; d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag, - 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); + port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); if (d == NULL) return 1; start_timer (); @@ -191,7 +194,7 @@ testInternalGet (int poll_flag) { cbc.pos = 0; c = curl_easy_init (); - curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11080/hello_world"); + curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); @@ -227,7 +230,7 @@ testInternalGet (int poll_flag) static int -testMultithreadedGet (int poll_flag) +testMultithreadedGet (int port, int poll_flag) { struct MHD_Daemon *d; CURL *c; @@ -235,11 +238,14 @@ testMultithreadedGet (int poll_flag) struct CBC cbc; CURLcode errornum; unsigned int i; + char url[64]; + + sprintf(url, "http://localhost:%d/hello_world", port); cbc.buf = buf; cbc.size = 2048; d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | poll_flag, - 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); + port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); if (d == NULL) return 16; start_timer (); @@ -247,7 +253,7 @@ testMultithreadedGet (int poll_flag) { cbc.pos = 0; c = curl_easy_init (); - curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world"); + curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); @@ -282,7 +288,7 @@ testMultithreadedGet (int poll_flag) } static int -testMultithreadedPoolGet (int poll_flag) +testMultithreadedPoolGet (int port, int poll_flag) { struct MHD_Daemon *d; CURL *c; @@ -290,11 +296,14 @@ testMultithreadedPoolGet (int poll_flag) struct CBC cbc; CURLcode errornum; unsigned int i; + char url[64]; + + sprintf(url, "http://localhost:%d/hello_world", port); cbc.buf = buf; cbc.size = 2048; d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag, - 1081, NULL, NULL, &ahc_echo, "GET", + port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END); if (d == NULL) return 16; @@ -303,7 +312,7 @@ testMultithreadedPoolGet (int poll_flag) { cbc.pos = 0; c = curl_easy_init (); - curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world"); + curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); @@ -338,7 +347,7 @@ testMultithreadedPoolGet (int poll_flag) } static int -testExternalGet () +testExternalGet (int port) { struct MHD_Daemon *d; CURL *c; @@ -355,12 +364,15 @@ testExternalGet () time_t start; struct timeval tv; unsigned int i; + char url[64]; + + sprintf(url, "http://localhost:%d/hello_world", port); multi = NULL; cbc.buf = buf; cbc.size = 2048; d = MHD_start_daemon (MHD_USE_DEBUG, - 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); + port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); if (d == NULL) return 256; start_timer (); @@ -374,7 +386,7 @@ testExternalGet () { cbc.pos = 0; c = curl_easy_init (); - curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world"); + curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); @@ -469,6 +481,7 @@ int main (int argc, char *const *argv) { unsigned int errorCount = 0; + int port = 1081; oneone = NULL != strstr (argv[0], "11"); if (0 != curl_global_init (CURL_GLOBAL_WIN32)) @@ -476,13 +489,13 @@ main (int argc, char *const *argv) response = MHD_create_response_from_buffer (strlen ("/hello_world"), "/hello_world", MHD_RESPMEM_MUST_COPY); - errorCount += testInternalGet (0); - errorCount += testMultithreadedGet (0); - errorCount += testMultithreadedPoolGet (0); - errorCount += testExternalGet (); - errorCount += testInternalGet (MHD_USE_POLL); - errorCount += testMultithreadedGet (MHD_USE_POLL); - errorCount += testMultithreadedPoolGet (MHD_USE_POLL); + errorCount += testInternalGet (port++, 0); + errorCount += testMultithreadedGet (port++, 0); + errorCount += testMultithreadedPoolGet (port++, 0); + errorCount += testExternalGet (port++); + errorCount += testInternalGet (port++, MHD_USE_POLL); + errorCount += testMultithreadedGet (port++, MHD_USE_POLL); + errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL); MHD_destroy_response (response); if (errorCount != 0) fprintf (stderr, "Error (code: %u)\n", errorCount); diff --git a/src/testcurl/perf_get_concurrent.c b/src/testcurl/perf_get_concurrent.c @@ -153,7 +153,7 @@ ahc_echo (void *cls, static pid_t -do_gets () +do_gets (int port) { pid_t ret; CURL *c; @@ -161,6 +161,9 @@ do_gets () unsigned int i; unsigned int j; pid_t par[PAR]; + char url[64]; + + sprintf(url, "http://localhost:%d/hello_world", port); ret = fork (); if (ret == -1) abort (); @@ -174,7 +177,7 @@ do_gets () for (i=0;i<ROUNDS;i++) { c = curl_easy_init (); - curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world"); + curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); @@ -220,16 +223,16 @@ join_gets (pid_t pid) static int -testInternalGet (int poll_flag) +testInternalGet (int port, int poll_flag) { struct MHD_Daemon *d; d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag, - 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); + port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); if (d == NULL) return 1; start_timer (); - join_gets (do_gets ()); + join_gets (do_gets (port)); stop (poll_flag ? "internal poll" : "internal select"); MHD_stop_daemon (d); return 0; @@ -237,40 +240,40 @@ testInternalGet (int poll_flag) static int -testMultithreadedGet (int poll_flag) +testMultithreadedGet (int port, int poll_flag) { struct MHD_Daemon *d; d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | poll_flag, - 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); + port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); if (d == NULL) return 16; start_timer (); - join_gets (do_gets ()); + join_gets (do_gets (port)); stop (poll_flag ? "thread with poll" : "thread with select"); MHD_stop_daemon (d); return 0; } static int -testMultithreadedPoolGet (int poll_flag) +testMultithreadedPoolGet (int port, int poll_flag) { struct MHD_Daemon *d; d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag, - 1081, NULL, NULL, &ahc_echo, "GET", + port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END); if (d == NULL) return 16; start_timer (); - join_gets (do_gets ()); + join_gets (do_gets (port)); stop (poll_flag ? "thread pool with poll" : "thread pool with select"); MHD_stop_daemon (d); return 0; } static int -testExternalGet () +testExternalGet (int port) { struct MHD_Daemon *d; pid_t pid; @@ -283,11 +286,11 @@ testExternalGet () int tret; d = MHD_start_daemon (MHD_USE_DEBUG, - 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); + port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); if (d == NULL) return 256; start_timer (); - pid = do_gets (); + pid = do_gets (port); while (0 == waitpid (pid, NULL, WNOHANG)) { max = 0; @@ -316,6 +319,7 @@ int main (int argc, char *const *argv) { unsigned int errorCount = 0; + int port = 1081; oneone = NULL != strstr (argv[0], "11"); if (0 != curl_global_init (CURL_GLOBAL_WIN32)) @@ -323,13 +327,13 @@ main (int argc, char *const *argv) response = MHD_create_response_from_buffer (strlen ("/hello_world"), "/hello_world", MHD_RESPMEM_MUST_COPY); - errorCount += testInternalGet (0); - errorCount += testMultithreadedGet (0); - errorCount += testMultithreadedPoolGet (0); - errorCount += testExternalGet (); - errorCount += testInternalGet (MHD_USE_POLL); - errorCount += testMultithreadedGet (MHD_USE_POLL); - errorCount += testMultithreadedPoolGet (MHD_USE_POLL); + errorCount += testInternalGet (port++, 0); + errorCount += testMultithreadedGet (port++, 0); + errorCount += testMultithreadedPoolGet (port++, 0); + errorCount += testExternalGet (port++); + errorCount += testInternalGet (port++, MHD_USE_POLL); + errorCount += testMultithreadedGet (port++, MHD_USE_POLL); + errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL); MHD_destroy_response (response); if (errorCount != 0) fprintf (stderr, "Error (code: %u)\n", errorCount);