commit 4b795e9fc603ccddeea2599c6919f80029837136
parent a22746fc8514f7c947b8433a0ee7d35c735a7bd6
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date: Thu, 10 Nov 2016 21:47:33 +0300
Added MHD_USE_AUTO and MHD_USE_AUTO_INTERNAL_THREAD to simplify using of MHD by multi-platform applications
Diffstat:
14 files changed, 127 insertions(+), 27 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,10 @@
+Thu Nov 10 21:50:35 MSK 2016
+ Added rejection in MHD_start_daemon() of invalid combinations
+ of daemon flags.
+ Added MHD_USE_AUTO and MHD_USE_AUTO_INTERNAL_THREAD for
+ automatic selection of polling function depending on
+ platform capabilities and requested mode. -EG
+
Thu Nov 10 17:49:56 MSK 2016
Ported "upgrade" tests to W32 and other platforms, used
"gnutls-cli" instead of "openssl" in tests, minor bugs
diff --git a/doc/examples/hellobrowser.c b/doc/examples/hellobrowser.c
@@ -39,7 +39,7 @@ main ()
{
struct MHD_Daemon *daemon;
- daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD, PORT, NULL, NULL,
+ daemon = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, PORT, NULL, NULL,
&answer_to_connection, NULL, MHD_OPTION_END);
if (NULL == daemon)
return 1;
diff --git a/doc/examples/simplepost.c b/doc/examples/simplepost.c
@@ -183,7 +183,7 @@ main ()
{
struct MHD_Daemon *daemon;
- daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD, PORT, NULL, NULL,
+ daemon = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, PORT, NULL, NULL,
&answer_to_connection, NULL,
MHD_OPTION_NOTIFY_COMPLETED, request_completed,
NULL, MHD_OPTION_END);
diff --git a/src/examples/chunked_example.c b/src/examples/chunked_example.c
@@ -78,8 +78,9 @@ main (int argc, char *const *argv)
printf ("%s PORT\n", argv[0]);
return 1;
}
- d = MHD_start_daemon (// MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
- MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ d = MHD_start_daemon (// MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ // MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
// MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
// MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
diff --git a/src/examples/demo.c b/src/examples/demo.c
@@ -883,11 +883,7 @@ main (int argc, char *const *argv)
MHD_RESPMEM_PERSISTENT);
mark_as_html (internal_error_response);
update_directory ();
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
-#ifdef EPOLL_SUPPORT
- | MHD_USE_EPOLL
-#endif
- ,
+ d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
port,
NULL, NULL,
&generate_page, NULL,
diff --git a/src/examples/demo_https.c b/src/examples/demo_https.c
@@ -932,11 +932,7 @@ main (int argc, char *const *argv)
MHD_RESPMEM_PERSISTENT);
mark_as_html (internal_error_response);
update_directory ();
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_TLS
-#ifdef EPOLL_SUPPORT
- | MHD_USE_EPOLL
-#endif
- ,
+ d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_TLS,
port,
NULL, NULL,
&generate_page, NULL,
diff --git a/src/examples/minimal_example.c b/src/examples/minimal_example.c
@@ -67,8 +67,9 @@ main (int argc, char *const *argv)
printf ("%s PORT\n", argv[0]);
return 1;
}
- d = MHD_start_daemon (// MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
- MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ d = MHD_start_daemon (// MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ // MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
// MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
// MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
diff --git a/src/examples/minimal_example_comet.c b/src/examples/minimal_example_comet.c
@@ -74,7 +74,7 @@ main (int argc, char *const *argv)
printf ("%s PORT\n", argv[0]);
return 1;
}
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
if (d == NULL)
diff --git a/src/examples/upgrade_example.c b/src/examples/upgrade_example.c
@@ -275,7 +275,7 @@ main (int argc,
printf ("%s PORT\n", argv[0]);
return 1;
}
- d = MHD_start_daemon (MHD_ALLOW_UPGRADE | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ d = MHD_start_daemon (MHD_ALLOW_UPGRADE | MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL,
&ahc_echo, NULL,
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
@@ -126,7 +126,7 @@ typedef intptr_t ssize_t;
* Current version of the library.
* 0x01093001 = 1.9.30-1.
*/
-#define MHD_VERSION 0x00095207
+#define MHD_VERSION 0x00095208
/**
* MHD-internal return code for "YES".
@@ -761,7 +761,28 @@ enum MHD_FLAG
* "Upgrade" may require usage of additional internal resources,
* which we do not want to use unless necessary.
*/
- MHD_ALLOW_UPGRADE = 32768
+ MHD_ALLOW_UPGRADE = 32768,
+
+ /**
+ * Automatically use best available polling function.
+ * Choice of polling function is also depend on other daemon options.
+ * If #MHD_USE_INTERNAL_POLLING_THREAD is specified then epoll, poll() or
+ * select() will be used (listed in decreasing preference order, first
+ * function available on system will be used).
+ * If #MHD_USE_THREAD_PER_CONNECTION is specified then poll() or select()
+ * will be used.
+ * If those flags are not specified then epoll or select() will be
+ * used (as the only suitable for MHD_get_fdset())
+ */
+ MHD_USE_AUTO = 65536,
+
+ /**
+ * Run using an internal thread (or thread pool) with best available on
+ * system polling function.
+ * This is combination of #MHD_USE_AUTO and #MHD_USE_INTERNAL_POLLING_THREAD
+ * flags.
+ */
+ MHD_USE_AUTO_INTERNAL_THREAD = MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD
};
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
@@ -4762,9 +4762,43 @@ MHD_start_daemon_va (unsigned int flags,
/* Check for invalid combinations of flags. */
if ( ((0 != (flags & MHD_USE_POLL)) && (0 != (flags & MHD_USE_EPOLL))) ||
((0 != (flags & MHD_USE_EPOLL)) && (0 != (flags & MHD_USE_THREAD_PER_CONNECTION))) ||
- ((0 != (flags & MHD_USE_POLL)) && (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD))) )
+ ((0 != (flags & MHD_USE_POLL)) && (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD))) ||
+ ((0 != (flags & MHD_USE_AUTO)) && (0 != (flags & (MHD_USE_POLL | MHD_USE_EPOLL)))) )
return NULL;
+ if (0 != (flags & MHD_USE_AUTO))
+ {
+ if (0 != (flags & MHD_USE_THREAD_PER_CONNECTION))
+ {
+ /* Thread per connection with internal polling thread. */
+#ifdef HAVE_POLL
+ flags |= MHD_USE_POLL;
+#else /* ! HAVE_POLL */
+ /* use select() - do not modify flags */
+#endif /* ! HAVE_POLL */
+ }
+ else if (0 != (flags & MHD_USE_INTERNAL_POLLING_THREAD))
+ {
+ /* Internal polling thread. */
+#if defined(EPOLL_SUPPORT)
+ flags |= MHD_USE_EPOLL;
+#elif defined(HAVE_POLL)
+ flags |= MHD_USE_POLL;
+#else /* !HAVE_POLL && !EPOLL_SUPPORT */
+ /* use select() - do not modify flags */
+#endif /* !HAVE_POLL && !EPOLL_SUPPORT */
+ }
+ else
+ {
+ /* Internal threads are not used - "external" polling mode. */
+#if defined(EPOLL_SUPPORT)
+ flags |= MHD_USE_EPOLL;
+#else /* ! EPOLL_SUPPORT */
+ /* use select() - do not modify flags */
+#endif /* ! EPOLL_SUPPORT */
+ }
+ }
+
if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
return NULL;
#ifdef EPOLL_SUPPORT
diff --git a/src/microhttpd/test_upgrade.c b/src/microhttpd/test_upgrade.c
@@ -1146,6 +1146,16 @@ main (int argc,
fprintf (stderr, "FAILED: Upgrade with external select, return code %d.\n", res);
else if (verbose)
printf ("PASSED: Upgrade with external select.\n");
+
+ /* Try external auto */
+ res = test_upgrade (MHD_USE_AUTO,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr, "FAILED: Upgrade with external 'auto', return code %d.\n", res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with external 'auto'.\n");
+
#ifdef EPOLL_SUPPORT
res = test_upgrade (MHD_USE_EPOLL,
0);
@@ -1164,6 +1174,14 @@ main (int argc,
fprintf (stderr, "FAILED: Upgrade with thread per connection, return code %d.\n", res);
else if (verbose)
printf ("PASSED: Upgrade with thread per connection.\n");
+
+ res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr, "FAILED: Upgrade with thread per connection and 'auto', return code %d.\n", res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with thread per connection and 'auto'.\n");
#ifdef HAVE_POLL
res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_POLL,
0);
@@ -1189,6 +1207,20 @@ main (int argc,
fprintf (stderr, "FAILED: Upgrade with internal select with thread pool, return code %d.\n", res);
else if (verbose)
printf ("PASSED: Upgrade with internal select with thread pool.\n");
+ res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr, "FAILED: Upgrade with internal 'auto' return code %d.\n", res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal 'auto'.\n");
+ res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
+ 2);
+ error_count += res;
+ if (res)
+ fprintf (stderr, "FAILED: Upgrade with internal 'auto' with thread pool, return code %d.\n", res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal 'auto' with thread pool.\n");
#ifdef HAVE_POLL
res = test_upgrade (MHD_USE_POLL_INTERNAL_THREAD,
0);
diff --git a/src/testcurl/perf_get.c b/src/testcurl/perf_get.c
@@ -226,7 +226,8 @@ testInternalGet (int port, int poll_flag)
}
curl_easy_cleanup (c);
}
- stop (poll_flag == MHD_USE_POLL ? "internal thread with poll()" :
+ stop (poll_flag == MHD_USE_AUTO ? "internal thread with 'auto'" :
+ poll_flag == MHD_USE_POLL ? "internal thread with poll()" :
poll_flag == MHD_USE_EPOLL ? "internal thread with epoll" : "internal thread with select()");
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -286,7 +287,8 @@ testMultithreadedGet (int port, int poll_flag)
}
curl_easy_cleanup (c);
}
- stop ((poll_flag & MHD_USE_POLL) ? "internal thread with poll() and thread per connection" :
+ stop ((poll_flag & MHD_USE_AUTO) ? "internal thread with 'auto' and thread per connection" :
+ (poll_flag & MHD_USE_POLL) ? "internal thread with poll() and thread per connection" :
(poll_flag & MHD_USE_EPOLL) ? "internal thread with epoll and thread per connection" :
"internal thread with select() and thread per connection");
MHD_stop_daemon (d);
@@ -347,7 +349,8 @@ testMultithreadedPoolGet (int port, int poll_flag)
}
curl_easy_cleanup (c);
}
- stop (0 != (poll_flag & MHD_USE_POLL) ? "internal thread pool with poll()" :
+ stop (0 != (poll_flag & MHD_USE_AUTO) ? "internal thread pool with 'auto'" :
+ 0 != (poll_flag & MHD_USE_POLL) ? "internal thread pool with poll()" :
0 != (poll_flag & MHD_USE_EPOLL) ? "internal thread pool with epoll" : "internal thread pool with select()");
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -521,6 +524,9 @@ main (int argc, char *const *argv)
"/hello_world",
MHD_RESPMEM_MUST_COPY);
errorCount += testExternalGet (port++);
+ errorCount += testInternalGet (port++, MHD_USE_AUTO);
+ errorCount += testMultithreadedGet (port++, MHD_USE_AUTO);
+ errorCount += testMultithreadedPoolGet (port++, MHD_USE_AUTO);
errorCount += testInternalGet (port++, 0);
errorCount += testMultithreadedGet (port++, 0);
errorCount += testMultithreadedPoolGet (port++, 0);
diff --git a/src/testcurl/perf_get_concurrent.c b/src/testcurl/perf_get_concurrent.c
@@ -233,7 +233,8 @@ static int
testInternalGet (int port, int poll_flag)
{
struct MHD_Daemon *d;
- const char * const test_desc = ((poll_flag & MHD_USE_POLL) ? "internal thread with poll()" :
+ const char * const test_desc = ((poll_flag & MHD_USE_AUTO) ? "internal thread with 'auto'" :
+ (poll_flag & MHD_USE_POLL) ? "internal thread with poll()" :
(poll_flag & MHD_USE_EPOLL) ? "internal thread with epoll" : "internal thread with select()");
const char * ret_val;
@@ -260,7 +261,8 @@ static int
testMultithreadedGet (int port, int poll_flag)
{
struct MHD_Daemon *d;
- const char * const test_desc = ((poll_flag & MHD_USE_POLL) ? "internal thread with poll() and thread per connection" :
+ const char * const test_desc = ((poll_flag & MHD_USE_AUTO) ? "internal thread with 'auto' and thread per connection" :
+ (poll_flag & MHD_USE_POLL) ? "internal thread with poll() and thread per connection" :
(poll_flag & MHD_USE_EPOLL) ? "internal thread with epoll and thread per connection"
: "internal thread with select() and thread per connection");
const char * ret_val;
@@ -287,7 +289,8 @@ static int
testMultithreadedPoolGet (int port, int poll_flag)
{
struct MHD_Daemon *d;
- const char * const test_desc = ((poll_flag & MHD_USE_POLL) ? "internal thread pool with poll()" :
+ const char * const test_desc = ((poll_flag & MHD_USE_AUTO) ? "internal thread pool with 'auto'" :
+ (poll_flag & MHD_USE_POLL) ? "internal thread pool with poll()" :
(poll_flag & MHD_USE_EPOLL) ? "internal thread poll with epoll" : "internal thread pool with select()");
const char * ret_val;
@@ -395,6 +398,9 @@ main (int argc, char *const *argv)
errorCount += testMultithreadedGet (port++, 0);
errorCount += testMultithreadedPoolGet (port++, 0);
errorCount += testExternalGet (port++);
+ errorCount += testInternalGet (port++, MHD_USE_AUTO);
+ errorCount += testMultithreadedGet (port++, MHD_USE_AUTO);
+ errorCount += testMultithreadedPoolGet (port++, MHD_USE_AUTO);
if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
{
errorCount += testInternalGet (port++, MHD_USE_POLL);