Ver Fonte

Added MHD_USE_AUTO and MHD_USE_AUTO_INTERNAL_THREAD to simplify using of MHD by multi-platform applications

Evgeny Grin (Karlson2k) há 9 anos atrás
pai
commit
4b795e9fc6

+ 7 - 0
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

+ 1 - 1
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;

+ 1 - 1
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);

+ 3 - 2
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]),

+ 1 - 5
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,

+ 1 - 5
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,

+ 3 - 2
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]),

+ 1 - 1
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)

+ 1 - 1
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,

+ 23 - 2
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
 
 };
 

+ 35 - 1
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

+ 32 - 0
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);

+ 9 - 3
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);

+ 9 - 3
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);