gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd] branch master updated (cd4d2f65 -> a19df909)


From: gnunet
Subject: [libmicrohttpd] branch master updated (cd4d2f65 -> a19df909)
Date: Thu, 23 Nov 2023 11:49:03 +0100

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from cd4d2f65 MHD_add_connection(): minor readability improvement
     new e35469ec Added detection of more conditions to process the data 
without waiting
     new 149db58a MHD_quiesce_daemon(): fixed return value if already quiesced
     new 5cbdf771 MHD_start_daemon(): moved daemon flags internal initialisation
     new a54fe75e MHD_start_daemon(): reject INTERNAL_POLLING_THREAD if threads 
are disabled
     new 53a69103 Moved user options counter to shorter its lifetime
     new 9dcf06f9 test_daemon: fixed to not skip if failed
     new 6fde86c2 test_digestauth2: fixed order of the initial checks
     new f6b5ec58 Improved daemon shutdown handling in external polling mode
     new af6dd184 Micro-optimisations for non-overridable FD_SETSIZE
     new 38e2c1fa Unified and simplified fd_set filling
     new b05555f8 Added new daemon flag MHD_USE_NO_THREAD_SAFETY
     new 67b1cdc2 Tests: added use of MHD_USE_NO_THREAD_SAFETY flag
     new a19df909 Officially support zero for MHD_OPTION_THREAD_POOL_SIZE

The 13 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/include/microhttpd.h                   |  23 ++-
 src/microhttpd/daemon.c                    | 247 +++++++++++++++++------------
 src/microhttpd/internal.h                  |  20 +--
 src/microhttpd/mhd_sockets.c               |   6 +
 src/microhttpd/test_client_put_stop.c      |   3 +-
 src/microhttpd/test_daemon.c               |  40 +++--
 src/microhttpd/test_options.c              |  21 +--
 src/microhttpd/test_set_panic.c            |   3 +-
 src/microhttpd/test_start_stop.c           |  23 ++-
 src/microhttpd/test_upgrade.c              |   5 +-
 src/testcurl/https/test_https_get_select.c |   4 +-
 src/testcurl/perf_get.c                    |   2 +-
 src/testcurl/test_add_conn.c               |   3 +-
 src/testcurl/test_basicauth.c              |   2 +-
 src/testcurl/test_callback.c               |   2 +-
 src/testcurl/test_delete.c                 |   2 +-
 src/testcurl/test_digestauth2.c            |  43 ++---
 src/testcurl/test_digestauth_emu_ext.c     |   2 +-
 src/testcurl/test_get.c                    |  15 +-
 src/testcurl/test_get_chunked.c            |   2 +-
 src/testcurl/test_get_close_keep_alive.c   |   2 +-
 src/testcurl/test_get_iovec.c              |   8 +-
 src/testcurl/test_get_sendfile.c           |   8 +-
 src/testcurl/test_head.c                   |   2 +-
 src/testcurl/test_large_put.c              |   2 +-
 src/testcurl/test_parse_cookies.c          |   2 +-
 src/testcurl/test_patch.c                  |   2 +-
 src/testcurl/test_post.c                   |   2 +-
 src/testcurl/test_post_loop.c              |   2 +-
 src/testcurl/test_postform.c               |   2 +-
 src/testcurl/test_process_arguments.c      |   2 +-
 src/testcurl/test_process_headers.c        |   2 +-
 src/testcurl/test_put.c                    |   2 +-
 src/testcurl/test_put_broken_len.c         |   2 +-
 src/testcurl/test_put_header_fold.c        |   2 +-
 src/testcurl/test_toolarge.c               |   3 +-
 src/testcurl/test_tricky.c                 |   3 +-
 src/testzzuf/test_get.c                    |  10 +-
 38 files changed, 321 insertions(+), 205 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index e1d12645..0c11d308 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -96,7 +96,7 @@ extern "C"
  * they are parsed as decimal numbers.
  * Example: 0x01093001 = 1.9.30-1.
  */
-#define MHD_VERSION 0x00097706
+#define MHD_VERSION 0x00097707
 
 /* If generic headers don't work on your platform, include headers
    which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t',
@@ -1531,7 +1531,19 @@ enum MHD_FLAG
    * Flag set to enable TLS 1.3 early data.  This has
    * security implications, be VERY careful when using this.
    */
-  MHD_USE_INSECURE_TLS_EARLY_DATA = 1U << 18
+  MHD_USE_INSECURE_TLS_EARLY_DATA = 1U << 18,
+
+  /**
+   * Indicates that MHD daemon will be used by application in single-threaded
+   * mode only.  When this flag is set then application must call any MHD
+   * function only within a single thread.
+   * This flag turns off some internal thread-safety and allows MHD making
+   * some of the internal optimisations suitable only for single-threaded
+   * environment.
+   * Not compatible with #MHD_USE_INTERNAL_POLLING_THREAD.
+   * @note Available since #MHD_VERSION 0x00097707
+   */
+  MHD_USE_NO_THREAD_SAFETY = 1U << 19
 
 };
 
@@ -1805,10 +1817,9 @@ enum MHD_OPTION
   /**
    * Number (`unsigned int`) of threads in thread pool. Enable
    * thread pooling by setting this value to to something
-   * greater than 1. Currently, thread mode must be
-   * #MHD_USE_INTERNAL_POLLING_THREAD if thread pooling is enabled
-   * (#MHD_start_daemon returns NULL for an unsupported thread
-   * mode).
+   * greater than 1.
+   * Can be used only for daemons started with 
#MHD_USE_INTERNAL_POLLING_THREAD.
+   * Ignored if followed by zero value.
    */
   MHD_OPTION_THREAD_POOL_SIZE = 14,
 
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index e88600c2..688d829d 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -732,6 +732,11 @@ urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
   const MHD_socket mhd_sckt = urh->mhd.socket;
   bool res = true;
 
+#ifndef HAS_FD_SETSIZE_OVERRIDABLE
+  (void) fd_setsize;  /* Mute compiler warning */
+  fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */
+#endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
+
   /* Do not add to 'es' only if socket is closed
    * or not used anymore. */
   if (MHD_INVALID_SOCKET != conn_sckt)
@@ -990,18 +995,47 @@ internal_get_fdset2 (struct MHD_Daemon *daemon,
   struct MHD_Connection *posn;
   enum MHD_Result result = MHD_YES;
   MHD_socket ls;
+  bool itc_added;
+
+#ifndef HAS_FD_SETSIZE_OVERRIDABLE
+  (void) fd_setsize;  /* Mute compiler warning */
+  fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */
+#endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
 
   if (daemon->shutdown)
-    return MHD_NO;
+    return MHD_YES;
 
-  ls = daemon->listen_fd;
-  if ( (MHD_INVALID_SOCKET != ls) &&
-       (! daemon->was_quiesced) &&
-       (! MHD_add_to_fd_set_ (ls,
-                              read_fd_set,
-                              max_fd,
-                              fd_setsize)) )
-    result = MHD_NO;
+  /* The order of FDs added is important for W32 sockets as W32 fd_set has
+     limits for number of added FDs instead of the limit for the higher
+     FD value. */
+
+  /* Add ITC FD first. The daemon must be able to respond on application
+     commands issued in other threads. */
+  itc_added = false;
+  if (MHD_ITC_IS_VALID_ (daemon->itc))
+  {
+    itc_added = MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
+                                    read_fd_set,
+                                    max_fd,
+                                    fd_setsize);
+    if (! itc_added)
+      result = MHD_NO;
+  }
+
+  ls = daemon->was_quiesced ? MHD_INVALID_SOCKET : daemon->listen_fd;
+  if (! itc_added &&
+      (MHD_INVALID_SOCKET != ls))
+  {
+    /* Add listen FD if ITC was not added. Listen FD could be used to signal
+       the daemon shutdown. */
+    if (MHD_add_to_fd_set_ (ls,
+                            read_fd_set,
+                            max_fd,
+                            fd_setsize))
+      ls = MHD_INVALID_SOCKET;   /* Already added */
+    else
+      result = MHD_NO;
+  }
 
   /* Add all sockets to 'except_fd_set' as well to watch for
    * out-of-band data. However, ignore errors if INFO_READ
@@ -1072,6 +1106,7 @@ internal_get_fdset2 (struct MHD_Daemon *daemon,
   }
 #endif /* MHD_WINSOCK_SOCKETS */
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+  if (1)
   {
     struct MHD_UpgradeResponseHandle *urh;
 
@@ -1088,6 +1123,21 @@ internal_get_fdset2 (struct MHD_Daemon *daemon,
     }
   }
 #endif
+
+  if (MHD_INVALID_SOCKET != ls)
+  {
+    /* The listen socket is present and hasn't been added */
+    if ((daemon->connections < daemon->connection_limit) &&
+        ! daemon->at_limit)
+    {
+      if (! MHD_add_to_fd_set_ (ls,
+                                read_fd_set,
+                                max_fd,
+                                fd_setsize))
+        result = MHD_NO;
+    }
+  }
+
 #if _MHD_DEBUG_CONNECT
 #ifdef HAVE_MESSAGES
   if (NULL != max_fd)
@@ -1198,13 +1248,14 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
 #endif /* HAVE_MESSAGES */
     return MHD_NO;
   }
+  fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */
 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
 
 #ifdef EPOLL_SUPPORT
   if (MHD_D_IS_USING_EPOLL_ (daemon))
   {
     if (daemon->shutdown)
-      return MHD_NO;
+      return MHD_YES;
 
     /* we're in epoll mode, use the epoll FD as a stand-in for
        the entire event set */
@@ -3101,9 +3152,9 @@ internal_add_connection (struct MHD_Daemon *daemon,
     return MHD_NO;
 
   if ((external_add) &&
-      MHD_D_IS_USING_THREADS_ (daemon))
+      MHD_D_IS_THREAD_SAFE_ (daemon))
   {
-    /* Connection is added externally and MHD is handling its own threads. */
+    /* Connection is added externally and MHD is thread safe mode. */
     MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
     DLL_insert (daemon->new_connections_head,
                 daemon->new_connections_tail,
@@ -3135,7 +3186,7 @@ new_connections_list_process_ (struct MHD_Daemon *daemon)
   struct MHD_Connection *local_head;
   struct MHD_Connection *local_tail;
   mhd_assert (daemon->have_new);
-  mhd_assert (MHD_D_IS_USING_THREADS_ (daemon));
+  mhd_assert (MHD_D_IS_THREAD_SAFE_ (daemon));
 
   /* Detach DL-list of new connections from the daemon for
    * following local processing. */
@@ -3570,8 +3621,8 @@ MHD_add_connection (struct MHD_Daemon *daemon,
   bool sk_spipe_supprs;
   struct sockaddr_storage addrstorage;
 
-  /* NOT thread safe with internal thread. TODO: fix thread safety. */
-  if ((! MHD_D_IS_USING_THREADS_ (daemon)) &&
+  /* TODO: fix atomic value reading */
+  if ((! MHD_D_IS_THREAD_SAFE_ (daemon)) &&
       (daemon->connection_limit <= daemon->connections))
     MHD_cleanup_connections (daemon);
 
@@ -4205,9 +4256,13 @@ MHD_get_timeout64 (struct MHD_Daemon *daemon,
 #endif
     return MHD_NO;
   }
-  if (daemon->data_already_pending)
+  if (daemon->data_already_pending
+      || (NULL != daemon->cleanup_head)
+      || daemon->resuming
+      || daemon->have_new
+      || daemon->shutdown)
   {
-    /* Some data already waiting to be processed. */
+    /* Some data or connection statuses already waiting to be processed. */
     *timeout64 = 0;
     return MHD_YES;
   }
@@ -4795,70 +4850,51 @@ MHD_select (struct MHD_Daemon *daemon,
   }
   else
   {
+    bool itc_added;
     /* accept only, have one thread per connection */
-    if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
-         (! daemon->was_quiesced) &&
-         (! MHD_add_to_fd_set_ (ls,
-                                &rs,
-                                &maxsock,
-                                (int) FD_SETSIZE)) )
+    itc_added = false;
+    if (MHD_ITC_IS_VALID_ (daemon->itc))
     {
+      itc_added = MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
+                                      &rs,
+                                      &maxsock,
+                                      (int) FD_SETSIZE);
+      if (! itc_added)
+      {
 #ifdef HAVE_MESSAGES
-      MHD_DLOG (daemon,
-                _ ("Could not add listen socket to fdset.\n"));
+        MHD_DLOG (daemon, _ ("Could not add control inter-thread " \
+                             "communication channel FD to fdset.\n"));
 #endif
-      return MHD_NO;
+        err_state = MHD_YES;
+      }
     }
-  }
-  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
-       (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
-                              &rs,
-                              &maxsock,
-                              (int) FD_SETSIZE)) )
-  {
-    bool retry_succeed;
-
-    retry_succeed = false;
-#if defined(MHD_WINSOCK_SOCKETS)
-    /* fdset limit reached, new connections
-       cannot be handled. Remove listen socket FD
-       from fdset and retry to add ITC FD. */
     if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
          (! daemon->was_quiesced) )
     {
-      FD_CLR (ls,
-              &rs);
-      if (MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
-                              &rs,
-                              &maxsock,
-                              (int) FD_SETSIZE))
-        retry_succeed = true;
-    }
-#endif /* MHD_WINSOCK_SOCKETS */
-
-    if (! retry_succeed)
-    {
+      /* Stop listening if we are at the configured connection limit */
+      /* If we're at the connection limit, no point in really
+         accepting new connections; however, make sure we do not miss
+         the shutdown OR the termination of an existing connection; so
+         only do this optimisation if we have a signaling ITC in
+         place. */
+      if (! itc_added ||
+          ((daemon->connections < daemon->connection_limit) &&
+           ! daemon->at_limit))
+      {
+        if (! MHD_add_to_fd_set_ (ls,
+                                  &rs,
+                                  &maxsock,
+                                  (int) FD_SETSIZE))
+        {
 #ifdef HAVE_MESSAGES
-      MHD_DLOG (daemon, _ ("Could not add control inter-thread " \
-                           "communication channel FD to fdset.\n"));
+          MHD_DLOG (daemon,
+                    _ ("Could not add listen socket to fdset.\n"));
 #endif
-      err_state = MHD_YES;
+          err_state = MHD_YES;
+        }
+      }
     }
   }
-  /* Stop listening if we are at the configured connection limit */
-  /* If we're at the connection limit, no point in really
-     accepting new connections; however, make sure we do not miss
-     the shutdown OR the termination of an existing connection; so
-     only do this optimization if we have a signaling ITC in
-     place. */
-  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
-       (MHD_ITC_IS_VALID_ (daemon->itc)) &&
-       ( (daemon->connections == daemon->connection_limit) ||
-         (daemon->at_limit) ) )
-  {
-    FD_CLR (ls,
-            &rs);
-  }
 
   if (MHD_NO != err_state)
     millisec = 0;
@@ -6125,7 +6161,8 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
   MHD_socket ret;
 
   ret = daemon->listen_fd;
-  if (MHD_INVALID_SOCKET == ret)
+  if ((MHD_INVALID_SOCKET == ret)
+      || daemon->was_quiesced)
     return MHD_INVALID_SOCKET;
   if ( (0 == (daemon->options & (MHD_USE_ITC))) &&
        MHD_D_IS_USING_THREADS_ (daemon) )
@@ -6196,6 +6233,14 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
  */
 struct MHD_InterimParams_
 {
+  /**
+   * The total number of all user options used.
+   *
+   * Contains number only of meaningful options, i.e. #MHD_OPTION_END and
+   * #MHD_OPTION_ARRAY themselves are not counted, while options inside
+   * #MHD_OPTION_ARRAY are counted.
+   */
+  size_t num_opts;
   /**
    * Set to 'true' if @a fdset_size is set by application.
    */
@@ -6578,7 +6623,7 @@ parse_options_va (struct MHD_Daemon *daemon,
   {
     /* Increase counter at start, so resulting value is number of
      * processed options, including any failed ones. */
-    daemon->num_opts++;
+    params->num_opts++;
     switch (opt)
     {
     case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
@@ -6690,18 +6735,14 @@ parse_options_va (struct MHD_Daemon *daemon,
                                          unsigned int);
       if (0 == daemon->worker_pool_size)
       {
-#ifdef HAVE_MESSAGES
-        MHD_DLOG (daemon,
-                  _ ("Warning: Zero size, specified for thread pool size," \
-                     " is ignored. Thread pool is not used.\n"));
-#endif
+        (void) 0; /* MHD_OPTION_THREAD_POOL_SIZE ignored, do nothing */
       }
       else if (1 == daemon->worker_pool_size)
       {
 #ifdef HAVE_MESSAGES
         MHD_DLOG (daemon,
-                  _ ("Warning: \"1\", specified for thread pool size, " \
-                     "is ignored. Thread pool is not used.\n"));
+                  _ ("Warning: value \"1\", specified as the thread pool " \
+                     "size, is ignored. Thread pool is not used.\n"));
 #endif
         daemon->worker_pool_size = 0;
       }
@@ -6974,7 +7015,7 @@ parse_options_va (struct MHD_Daemon *daemon,
                                          VfprintfFunctionPointerType);
       daemon->custom_error_log_cls = va_arg (ap,
                                              void *);
-      if (1 != daemon->num_opts)
+      if (1 != params->num_opts)
         MHD_DLOG (daemon,
                   _ ("MHD_OPTION_EXTERNAL_LOGGER is not the first option "
                      "specified for the daemon. Some messages may be "
@@ -7045,7 +7086,7 @@ parse_options_va (struct MHD_Daemon *daemon,
 #endif /* HAVE_MESSAGES */
       break;
     case MHD_OPTION_ARRAY:
-      daemon->num_opts--; /* Do not count MHD_OPTION_ARRAY */
+      params->num_opts--; /* Do not count MHD_OPTION_ARRAY */
       oa = va_arg (ap, struct MHD_OptionItem *);
       i = 0;
       while (MHD_OPTION_END != (opt = oa[i].option))
@@ -7590,6 +7631,10 @@ MHD_start_daemon_va (unsigned int flags,
   MHD_check_global_init_ ();
   eflags = (enum MHD_FLAG) flags;
   pflags = &eflags;
+
+  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
+    *pflags |= MHD_USE_INTERNAL_POLLING_THREAD; /* Force enable, log warning 
later if needed */
+
 #ifndef HAVE_INET6
   if (0 != (*pflags & MHD_USE_IPv6))
     return NULL;
@@ -7618,6 +7663,16 @@ MHD_start_daemon_va (unsigned int flags,
     return NULL;
 #endif /* ! UPGRADE_SUPPORT */
   }
+#ifdef MHD_USE_THREADS
+  if ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD) ==
+      ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD)
+       & *pflags))
+    return NULL; /* Cannot be thread-unsafe with multiple threads */
+#else  /* ! MHD_USE_THREADS */
+  if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
+    return NULL;
+#endif /* ! MHD_USE_THREADS */
+
   if (NULL == dh)
     return NULL;
 
@@ -7653,6 +7708,16 @@ MHD_start_daemon_va (unsigned int flags,
 #endif
   }
 
+  if (0 != (*pflags & MHD_USE_NO_THREAD_SAFETY))
+    *pflags = (*pflags & ~((enum MHD_FLAG) MHD_USE_ITC)); /* useless in 
single-threaded environment */
+  else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
+  {
+#ifdef HAVE_LISTEN_SHUTDOWN
+    if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
+#endif
+    *pflags |= MHD_USE_ITC;       /* yes, must use ITC to signal thread */
+  }
+
   if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
     return NULL;
   interim_params = (struct MHD_InterimParams_ *) \
@@ -7719,21 +7784,6 @@ MHD_start_daemon_va (unsigned int flags,
   daemon->fdset_size_set_by_app = false;
 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */
 
-  if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) &&
-       (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) )
-  {
-    /* Log warning message later, when log parameters are processes */
-    *pflags |= MHD_USE_INTERNAL_POLLING_THREAD;
-  }
-  if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
-    *pflags = (*pflags & ~((enum MHD_FLAG) MHD_USE_ITC)); /* useless if we are 
using 'external' select */
-  else
-  {
-#ifdef HAVE_LISTEN_SHUTDOWN
-    if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
-#endif
-    *pflags |= MHD_USE_ITC;       /* yes, must use ITC to signal thread */
-  }
 #ifdef DAUTH_SUPPORT
   daemon->digest_auth_rand_size = 0;
   daemon->digest_auth_random = NULL;
@@ -7746,6 +7796,7 @@ MHD_start_daemon_va (unsigned int flags,
   }
 #endif /* HTTPS_SUPPORT */
 
+  interim_params->num_opts = 0;
   interim_params->fdset_size_set = false;
   interim_params->fdset_size = 0;
   interim_params->listen_fd_set = false;
@@ -9376,12 +9427,8 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
     return NULL;
 #endif /* ! EPOLL_SUPPORT */
   case MHD_DAEMON_INFO_CURRENT_CONNECTIONS:
-    if (! MHD_D_IS_USING_THREADS_ (daemon))
-    {
-      /* Assume that MHD_run() in not called in other thread
-       * at the same time. */
+    if (! MHD_D_IS_THREAD_SAFE_ (daemon))
       MHD_cleanup_connections (daemon);
-    }
 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
     else if (daemon->worker_pool)
     {
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 3d7d774a..667b6071 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -2443,15 +2443,6 @@ struct MHD_Daemon
    */
   unsigned int listen_backlog_size;
 
-  /**
-   * The number of user options used.
-   *
-   * Contains number of only meaningful options, i.e. #MHD_OPTION_END
-   * and #MHD_OPTION_ARRAY are not counted, while options inside
-   * #MHD_OPTION_ARRAY are counted.
-   */
-  size_t num_opts;
-
   /* TODO: replace with a single member */
   /**
    * The value to be returned by #MHD_get_daemon_info()
@@ -2560,6 +2551,12 @@ struct MHD_Daemon
  */
 #define MHD_D_IS_USING_THREAD_PER_CONN_(d) \
   (0 != ((d)->options & MHD_USE_THREAD_PER_CONNECTION))
+
+/**
+ * Check whether the @a d daemon has thread-safety enabled.
+ */
+#define MHD_D_IS_THREAD_SAFE_(d) \
+  (0 == ((d)->options & MHD_USE_NO_THREAD_SAFETY))
 #else  /* ! MHD_USE_THREADS */
 /**
  * Checks whether the @a d daemon is using internal polling thread
@@ -2569,6 +2566,11 @@ struct MHD_Daemon
  * Checks whether the @a d daemon is using thread-per-connection mode
  */
 #define MHD_D_IS_USING_THREAD_PER_CONN_(d) ((void) d, 0)
+
+/**
+ * Check whether the @a d daemon has thread-safety enabled.
+ */
+#define MHD_D_IS_THREAD_SAFE_(d) ((void) d, 0)
 #endif /* ! MHD_USE_THREADS */
 
 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
diff --git a/src/microhttpd/mhd_sockets.c b/src/microhttpd/mhd_sockets.c
index bd7f30d3..0b348d83 100644
--- a/src/microhttpd/mhd_sockets.c
+++ b/src/microhttpd/mhd_sockets.c
@@ -386,6 +386,12 @@ MHD_add_to_fd_set_ (MHD_socket fd,
   if ( (NULL == set) ||
        (MHD_INVALID_SOCKET == fd) )
     return 0;
+
+#ifndef HAS_FD_SETSIZE_OVERRIDABLE
+  (void) fd_setsize;  /* Mute compiler warning */
+  fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */
+#endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
+
   if (! MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (fd,
                                          set,
                                          fd_setsize))
diff --git a/src/microhttpd/test_client_put_stop.c 
b/src/microhttpd/test_client_put_stop.c
index 388bc12d..aaf5c829 100644
--- a/src/microhttpd/test_client_put_stop.c
+++ b/src/microhttpd/test_client_put_stop.c
@@ -1979,7 +1979,8 @@ startTestMhdDaemon (enum testMhdThreadsType thrType,
 
   if (testMhdThreadExternal == thrType)
     d = MHD_start_daemon (((unsigned int) pollType)
-                          | (verbose ? MHD_USE_ERROR_LOG : 0),
+                          | (verbose ? MHD_USE_ERROR_LOG : 0)
+                          | MHD_USE_NO_THREAD_SAFETY,
                           *pport, NULL, NULL,
                           &ahcCheck, *ahc_param,
                           MHD_OPTION_URI_LOG_CALLBACK, &check_uri_cb,
diff --git a/src/microhttpd/test_daemon.c b/src/microhttpd/test_daemon.c
index b759bc98..9239ada5 100644
--- a/src/microhttpd/test_daemon.c
+++ b/src/microhttpd/test_daemon.c
@@ -1,6 +1,7 @@
 /*
      This file is part of libmicrohttpd
      Copyright (C) 2007, 2017 Christian Grothoff
+     Copyright (C) 2014--2023  Evgeny Grin (Karlson2k)
 
      libmicrohttpd is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -22,6 +23,7 @@
  * @file test_daemon.c
  * @brief  Testcase for libmicrohttpd starts and stops
  * @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
  */
 
 #include "platform.h"
@@ -106,7 +108,7 @@ testStartStop (void)
     fprintf (stderr,
              "Failed to start daemon on port %u\n",
              (unsigned int) 0);
-    exit (77);
+    exit (3);
   }
   MHD_stop_daemon (d);
   return 0;
@@ -114,14 +116,15 @@ testStartStop (void)
 
 
 static unsigned int
-testExternalRun (void)
+testExternalRun (int use_no_thread_safe)
 {
   struct MHD_Daemon *d;
   fd_set rs;
   MHD_socket maxfd;
   int i;
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG
+                        | (use_no_thread_safe ? MHD_USE_NO_THREAD_SAFETY : 0),
                         0,
                         &apc_all, NULL,
                         &ahc_nothing, NULL,
@@ -133,10 +136,9 @@ testExternalRun (void)
     fprintf (stderr,
              "Failed to start daemon on port %u\n",
              (unsigned int) 0);
-    exit (77);
+    exit (3);
   }
-  i = 0;
-  while (i < 15)
+  for (i = 0; i < 15; ++i)
   {
     maxfd = 0;
     FD_ZERO (&rs);
@@ -147,14 +149,13 @@ testExternalRun (void)
                "Failed in MHD_get_fdset().\n");
       return 256;
     }
-    if (MHD_run (d) == MHD_NO)
+    if (MHD_NO == MHD_run (d))
     {
       MHD_stop_daemon (d);
       fprintf (stderr,
                "Failed in MHD_run().\n");
       return 8;
     }
-    i++;
   }
   MHD_stop_daemon (d);
   return 0;
@@ -176,8 +177,8 @@ testThread (void)
   {
     fprintf (stderr,
              "Failed to start daemon on port %u.\n",
-             (unsigned int) 1082);
-    exit (77);
+             (unsigned int) 0);
+    exit (3);
   }
   if (MHD_run (d) != MHD_NO)
   {
@@ -207,7 +208,7 @@ testMultithread (void)
     fprintf (stderr,
              "Failed to start daemon on port %u\n",
              (unsigned int) 0);
-    exit (77);
+    exit (3);
   }
   if (MHD_run (d) != MHD_NO)
   {
@@ -225,13 +226,22 @@ main (int argc,
       char *const *argv)
 {
   unsigned int errorCount = 0;
+  int has_threads_support;
   (void) argc; (void) argv; /* Unused. Silent compiler warning. */
 
+  has_threads_support =
+    (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_THREADS));
   errorCount += testStartError ();
-  errorCount += testStartStop ();
-  errorCount += testExternalRun ();
-  errorCount += testThread ();
-  errorCount += testMultithread ();
+  if (has_threads_support)
+    errorCount += testStartStop ();
+  if (has_threads_support)
+    errorCount += testExternalRun (0);
+  errorCount += testExternalRun (! 0);
+  if (has_threads_support)
+  {
+    errorCount += testThread ();
+    errorCount += testMultithread ();
+  }
   if (0 != errorCount)
     fprintf (stderr,
              "Error (code: %u)\n",
diff --git a/src/microhttpd/test_options.c b/src/microhttpd/test_options.c
index 7be7666d..9e2d3b45 100644
--- a/src/microhttpd/test_options.c
+++ b/src/microhttpd/test_options.c
@@ -102,7 +102,7 @@ test_ip_addr_option (void)
 
   ret = 0;
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR, &daemon_ip_addr,
                         MHD_OPTION_END);
@@ -120,7 +120,7 @@ test_ip_addr_option (void)
 
 
   daemon_ip_addr.sin_port = htons (port4);
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR_LEN,
                         (socklen_t) sizeof(daemon_ip_addr), &daemon_ip_addr,
@@ -138,7 +138,7 @@ test_ip_addr_option (void)
   MHD_stop_daemon (d);
 
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR_LEN,
                         (socklen_t) (sizeof(daemon_ip_addr) / 2),
@@ -154,7 +154,7 @@ test_ip_addr_option (void)
 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
 
   daemon_ip_addr.sin_len = (socklen_t) sizeof(daemon_ip_addr);
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR_LEN,
                         (socklen_t) sizeof(daemon_ip_addr), &daemon_ip_addr,
@@ -173,7 +173,7 @@ test_ip_addr_option (void)
 
 
   daemon_ip_addr.sin_len = (socklen_t) (sizeof(daemon_ip_addr) / 2);
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR_LEN,
                         (socklen_t) sizeof(daemon_ip_addr), &daemon_ip_addr,
@@ -189,7 +189,8 @@ test_ip_addr_option (void)
 
 
 #if defined(HAVE_INET6) && defined(USE_IPV6_TESTING)
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_IPv6, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_IPv6
+                        | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR, &daemon_ip_addr6,
                         MHD_OPTION_END);
@@ -207,7 +208,7 @@ test_ip_addr_option (void)
 
 
   daemon_ip_addr6.sin6_port = htons (port6);
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR_LEN,
                         (socklen_t) sizeof(daemon_ip_addr6), &daemon_ip_addr6,
@@ -225,7 +226,7 @@ test_ip_addr_option (void)
   MHD_stop_daemon (d);
 
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR_LEN,
                         (socklen_t) (sizeof(daemon_ip_addr6) / 2),
@@ -241,7 +242,7 @@ test_ip_addr_option (void)
 #if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN)
 
   daemon_ip_addr6.sin6_len = (socklen_t) sizeof(daemon_ip_addr6);
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR_LEN,
                         (socklen_t) sizeof(daemon_ip_addr6), &daemon_ip_addr6,
@@ -260,7 +261,7 @@ test_ip_addr_option (void)
 
 
   daemon_ip_addr6.sin6_len = (socklen_t) (sizeof(daemon_ip_addr6) / 2);
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0,
                         NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_SOCK_ADDR_LEN,
                         (socklen_t) sizeof(daemon_ip_addr6), &daemon_ip_addr6,
diff --git a/src/microhttpd/test_set_panic.c b/src/microhttpd/test_set_panic.c
index cec361f6..ca9a0375 100644
--- a/src/microhttpd/test_set_panic.c
+++ b/src/microhttpd/test_set_panic.c
@@ -1469,7 +1469,8 @@ startTestMhdDaemon (enum testMhdThreadsType thrType,
 
   if (testMhdThreadExternal == thrType)
     d = MHD_start_daemon (((unsigned int) pollType)
-                          | (verbose ? MHD_USE_ERROR_LOG : 0),
+                          | (verbose ? MHD_USE_ERROR_LOG : 0)
+                          | MHD_USE_NO_THREAD_SAFETY,
                           *pport, NULL, NULL,
                           &ahcCheck, *ahc_param,
                           MHD_OPTION_NOTIFY_CONNECTION, &socket_cb,
diff --git a/src/microhttpd/test_start_stop.c b/src/microhttpd/test_start_stop.c
index a64f3011..1031e12e 100644
--- a/src/microhttpd/test_start_stop.c
+++ b/src/microhttpd/test_start_stop.c
@@ -101,15 +101,31 @@ testMultithreadedPoolGet (unsigned int poll_flag)
 }
 
 
+static unsigned int
+testExternalGet (void)
+{
+  struct MHD_Daemon *d;
+
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+                        0, NULL, NULL,
+                        &ahc_echo, NULL,
+                        MHD_OPTION_END);
+  if (NULL == d)
+    return 8;
+  MHD_stop_daemon (d);
+  return 0;
+}
+
+
 #endif
 
 
 static unsigned int
-testExternalGet (void)
+testExternalGetSingleThread (void)
 {
   struct MHD_Daemon *d;
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         0, NULL, NULL,
                         &ahc_echo, NULL,
                         MHD_OPTION_END);
@@ -132,8 +148,9 @@ main (int argc,
   errorCount += testInternalGet (0);
   errorCount += testMultithreadedGet (0);
   errorCount += testMultithreadedPoolGet (0);
-#endif
   errorCount += testExternalGet ();
+#endif
+  errorCount += testExternalGetSingleThread ();
 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
   {
diff --git a/src/microhttpd/test_upgrade.c b/src/microhttpd/test_upgrade.c
index 0abd5f10..22b15090 100644
--- a/src/microhttpd/test_upgrade.c
+++ b/src/microhttpd/test_upgrade.c
@@ -1275,7 +1275,8 @@ test_upgrade (unsigned int flags,
   done = false;
 
   if (! test_tls)
-    d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE,
+    d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE
+                          | MHD_USE_ITC,
                           global_port,
                           NULL, NULL,
                           &ahc_upgrade, NULL,
@@ -1289,7 +1290,7 @@ test_upgrade (unsigned int flags,
 #ifdef HTTPS_SUPPORT
   else
     d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE
-                          | MHD_USE_TLS,
+                          | MHD_USE_TLS | MHD_USE_ITC,
                           global_port,
                           NULL, NULL,
                           &ahc_upgrade, NULL,
diff --git a/src/testcurl/https/test_https_get_select.c 
b/src/testcurl/https/test_https_get_select.c
index 1939ccff..8ce55e2c 100644
--- a/src/testcurl/https/test_https_get_select.c
+++ b/src/testcurl/https/test_https_get_select.c
@@ -278,7 +278,9 @@ main (int argc, char *const *argv)
 #ifdef EPOLL_SUPPORT
   errorCount += testExternalGet (MHD_USE_EPOLL);
 #endif
-  errorCount += testExternalGet (0);
+  if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+    errorCount += testExternalGet (MHD_NO_FLAG);
+  errorCount += testExternalGet (MHD_USE_NO_THREAD_SAFETY);
   curl_global_cleanup ();
   if (errorCount != 0)
     fprintf (stderr, "Failed test: %s, error: %u.\n", argv[0], errorCount);
diff --git a/src/testcurl/perf_get.c b/src/testcurl/perf_get.c
index 0a8af562..c9f400a3 100644
--- a/src/testcurl/perf_get.c
+++ b/src/testcurl/perf_get.c
@@ -458,7 +458,7 @@ testExternalGet (uint16_t port)
   multi = NULL;
   cbc.buf = buf;
   cbc.size = 2048;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL,
                         &ahc_echo, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_add_conn.c b/src/testcurl/test_add_conn.c
index 4fd651b3..2539b5f5 100644
--- a/src/testcurl/test_add_conn.c
+++ b/src/testcurl/test_add_conn.c
@@ -739,8 +739,7 @@ startTestMhdDaemon (enum testMhdThreadsType thrType,
 
   if (testMhdThreadExternal == thrType)
     d = MHD_start_daemon (((unsigned int) thrType) | ((unsigned int) pollType)
-                          | (thrType == testMhdThreadExternal ?
-                             0 : MHD_USE_ITC)
+                          | MHD_USE_NO_THREAD_SAFETY
                           | (no_listen ? MHD_USE_NO_LISTEN_SOCKET : 0)
                           | MHD_USE_ERROR_LOG,
                           *pport, NULL, NULL,
diff --git a/src/testcurl/test_basicauth.c b/src/testcurl/test_basicauth.c
index 963639c9..d6fe1427 100644
--- a/src/testcurl/test_basicauth.c
+++ b/src/testcurl/test_basicauth.c
@@ -647,7 +647,7 @@ testBasicAuth (void)
   else
     port = 4210;
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL,
                         &ahc_echo, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_callback.c b/src/testcurl/test_callback.c
index 510043cc..3cc28c5f 100644
--- a/src/testcurl/test_callback.c
+++ b/src/testcurl/test_callback.c
@@ -141,7 +141,7 @@ main (int argc, char **argv)
   else
     port = 1140;
 
-  d = MHD_start_daemon (0,
+  d = MHD_start_daemon (MHD_USE_NO_THREAD_SAFETY,
                         port,
                         NULL,
                         NULL,
diff --git a/src/testcurl/test_delete.c b/src/testcurl/test_delete.c
index 681afe30..81fa9986 100644
--- a/src/testcurl/test_delete.c
+++ b/src/testcurl/test_delete.c
@@ -389,7 +389,7 @@ testExternalDelete (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port,
                         NULL, NULL, &ahc_echo, &done_flag,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_digestauth2.c b/src/testcurl/test_digestauth2.c
index ce2def62..2ec78e26 100644
--- a/src/testcurl/test_digestauth2.c
+++ b/src/testcurl/test_digestauth2.c
@@ -1366,7 +1366,7 @@ testDigestAuth (void)
     if (test_bind_uri)
       dauth_nonce_bind |= MHD_DAUTH_BIND_NONCE_URI_PARAMS;
 
-    d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+    d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                           port, NULL, NULL,
                           &ahc_echo, &rq_tr,
                           MHD_OPTION_DIGEST_AUTH_RANDOM_COPY,
@@ -1532,6 +1532,27 @@ main (int argc, char *const *argv)
              0xFF & (curl_info->version_num >> 0));
     return 77;
   }
+
+  if (test_sha256)
+  {
+    if (curl_sspi)
+    {
+      fprintf (stderr, "Windows SSPI API does not support SHA-256 digests.\n");
+      return 77;
+    }
+    else if (CURL_VERSION_BITS (7,57,0) > curl_info->version_num)
+    {
+      fprintf (stderr, "Required libcurl at least version 7.57.0 "
+               "to run this test with SHA-256.\n");
+      fprintf (stderr, "This libcurl version %u.%u.%u "
+               "does not support SHA-256.\n",
+               0xFF & (curl_info->version_num >> 16),
+               0xFF & (curl_info->version_num >> 8),
+               0xFF & (curl_info->version_num >> 0));
+      return 77;
+    }
+  }
+
   if (test_userhash)
   {
     if (curl_sspi)
@@ -1571,26 +1592,6 @@ main (int argc, char *const *argv)
   else
     curl_uses_usehash = 0;
 
-  if (test_sha256)
-  {
-    if (curl_sspi)
-    {
-      fprintf (stderr, "Windows SSPI API does not support SHA-256 digests.\n");
-      return 77;
-    }
-    else if (CURL_VERSION_BITS (7,57,0) > curl_info->version_num)
-    {
-      fprintf (stderr, "Required libcurl at least version 7.57.0 "
-               "to run this test with SHA-256.\n");
-      fprintf (stderr, "This libcurl version %u.%u.%u "
-               "does not support SHA-256.\n",
-               0xFF & (curl_info->version_num >> 16),
-               0xFF & (curl_info->version_num >> 8),
-               0xFF & (curl_info->version_num >> 0));
-      return 77;
-    }
-  }
-
   test_global_init ();
 
   errorCount += testDigestAuth ();
diff --git a/src/testcurl/test_digestauth_emu_ext.c 
b/src/testcurl/test_digestauth_emu_ext.c
index 7a6e8e7b..8506a567 100644
--- a/src/testcurl/test_digestauth_emu_ext.c
+++ b/src/testcurl/test_digestauth_emu_ext.c
@@ -820,7 +820,7 @@ testDigestAuthEmu (void)
   else
     port = 4210;
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL,
                         &ahc_echo, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_get.c b/src/testcurl/test_get.c
index b44c8370..812aa840 100644
--- a/src/testcurl/test_get.c
+++ b/src/testcurl/test_get.c
@@ -394,7 +394,7 @@ testMultithreadedPoolGet (uint32_t poll_flag)
 
 
 static unsigned int
-testExternalGet (void)
+testExternalGet (int thread_unsafe)
 {
   struct MHD_Daemon *d;
   CURL *c;
@@ -424,7 +424,8 @@ testExternalGet (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG
+                        | (thread_unsafe ? MHD_USE_NO_THREAD_SAFETY : 0),
                         global_port, NULL, NULL,
                         &ahc_echo, NULL,
                         MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
@@ -890,14 +891,20 @@ main (int argc, char *const *argv)
   if (0 != curl_global_init (CURL_GLOBAL_WIN32))
     return 2;
   global_port = 0;
-  test_result = testExternalGet ();
+  test_result = testExternalGet (! 0);
   if (test_result)
-    fprintf (stderr, "FAILED: testExternalGet () - %u.\n", test_result);
+    fprintf (stderr, "FAILED: testExternalGet (!0) - %u.\n", test_result);
   else if (verbose)
     printf ("PASSED: testExternalGet ().\n");
   errorCount += test_result;
   if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
   {
+    test_result += testExternalGet (0);
+    if (test_result)
+      fprintf (stderr, "FAILED: testExternalGet (0) - %u.\n", test_result);
+    else if (verbose)
+      printf ("PASSED: testExternalGet ().\n");
+    errorCount += test_result;
     test_result += testInternalGet (0);
     if (test_result)
       fprintf (stderr, "FAILED: testInternalGet (0) - %u.\n", test_result);
diff --git a/src/testcurl/test_get_chunked.c b/src/testcurl/test_get_chunked.c
index 1b985ce2..9ffa8041 100644
--- a/src/testcurl/test_get_chunked.c
+++ b/src/testcurl/test_get_chunked.c
@@ -591,7 +591,7 @@ testExternalGet (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
                         MHD_OPTION_END);
diff --git a/src/testcurl/test_get_close_keep_alive.c 
b/src/testcurl/test_get_close_keep_alive.c
index 5771bec9..b84e9640 100644
--- a/src/testcurl/test_get_close_keep_alive.c
+++ b/src/testcurl/test_get_close_keep_alive.c
@@ -958,7 +958,7 @@ startTestMhdDaemon (enum testMhdThreadsType thrType,
 
   if (testMhdThreadExternal == thrType)
     d = MHD_start_daemon (((unsigned int) thrType) | ((unsigned int) pollType)
-                          | MHD_USE_ERROR_LOG,
+                          | MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                           *pport, NULL, NULL,
                           &ahc_echo, NULL,
                           MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
diff --git a/src/testcurl/test_get_iovec.c b/src/testcurl/test_get_iovec.c
index 00e4fa3e..f1a83ece 100644
--- a/src/testcurl/test_get_iovec.c
+++ b/src/testcurl/test_get_iovec.c
@@ -481,7 +481,7 @@ testMultithreadedPoolGet (void)
 
 
 static unsigned int
-testExternalGet (void)
+testExternalGet (int thread_unsafe)
 {
   struct MHD_Daemon *d;
   CURL *c;
@@ -516,7 +516,8 @@ testExternalGet (void)
   cbc.buf = (char *) readbuf;
   cbc.size = sizeof(readbuf);
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG
+                        | (thread_unsafe ? MHD_USE_NO_THREAD_SAFETY : 0),
                         port, NULL, NULL, &ahc_cont, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
                         MHD_OPTION_END);
@@ -773,8 +774,9 @@ main (int argc, char *const *argv)
     errorCount += testMultithreadedGet ();
     errorCount += testMultithreadedPoolGet ();
     errorCount += testUnknownPortGet ();
+    errorCount += testExternalGet (0);
   }
-  errorCount += testExternalGet ();
+  errorCount += testExternalGet (! 0);
   if (errorCount != 0)
     fprintf (stderr, "Error (code: %u)\n", errorCount);
   curl_global_cleanup ();
diff --git a/src/testcurl/test_get_sendfile.c b/src/testcurl/test_get_sendfile.c
index 698a7c2e..01be8122 100644
--- a/src/testcurl/test_get_sendfile.c
+++ b/src/testcurl/test_get_sendfile.c
@@ -337,7 +337,7 @@ testMultithreadedPoolGet (void)
 
 
 static unsigned int
-testExternalGet (void)
+testExternalGet (int thread_unsafe)
 {
   struct MHD_Daemon *d;
   CURL *c;
@@ -373,7 +373,8 @@ testExternalGet (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG
+                        | (thread_unsafe ? MHD_USE_NO_THREAD_SAFETY : 0),
                         port, NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
                         MHD_OPTION_END);
@@ -660,8 +661,9 @@ main (int argc, char *const *argv)
     errorCount += testMultithreadedGet ();
     errorCount += testMultithreadedPoolGet ();
     errorCount += testUnknownPortGet ();
+    errorCount += testExternalGet (0);
   }
-  errorCount += testExternalGet ();
+  errorCount += testExternalGet (! 0);
   if (errorCount != 0)
     fprintf (stderr, "Error (code: %u)\n", errorCount);
   curl_global_cleanup ();
diff --git a/src/testcurl/test_head.c b/src/testcurl/test_head.c
index 4f820880..226663d3 100644
--- a/src/testcurl/test_head.c
+++ b/src/testcurl/test_head.c
@@ -756,7 +756,7 @@ testHead (void)
   else
     port = 4220 + oneone ? 0 : 1;
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL,
                         &ahcCheck, &ahc_param,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_large_put.c b/src/testcurl/test_large_put.c
index d2612fa8..64669a44 100644
--- a/src/testcurl/test_large_put.c
+++ b/src/testcurl/test_large_put.c
@@ -647,7 +647,7 @@ testPutExternal (void)
   cbc.size = 2048;
   cbc.pos = 0;
   multi = NULL;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port,
                         NULL, NULL, &ahc_echo, &done_flag,
                         MHD_OPTION_CONNECTION_MEMORY_LIMIT,
diff --git a/src/testcurl/test_parse_cookies.c 
b/src/testcurl/test_parse_cookies.c
index d81f0765..41c408a9 100644
--- a/src/testcurl/test_parse_cookies.c
+++ b/src/testcurl/test_parse_cookies.c
@@ -1646,7 +1646,7 @@ testExternalPolling (void)
   else
     port = 1340 + oneone ? 0 : 6 + (uint16_t) (1 + discp_level);
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL,
                         &ahcCheck, &ahc_param,
                         MHD_OPTION_CLIENT_DISCIPLINE_LVL,
diff --git a/src/testcurl/test_patch.c b/src/testcurl/test_patch.c
index e5f37901..c13712e0 100644
--- a/src/testcurl/test_patch.c
+++ b/src/testcurl/test_patch.c
@@ -374,7 +374,7 @@ testExternalPut (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port,
                         NULL, NULL, &ahc_echo, &done_flag,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_post.c b/src/testcurl/test_post.c
index 3f64c0a4..58409cc1 100644
--- a/src/testcurl/test_post.c
+++ b/src/testcurl/test_post.c
@@ -433,7 +433,7 @@ testExternalPost (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_post_loop.c b/src/testcurl/test_post_loop.c
index 7144abdd..5f2b7ad3 100644
--- a/src/testcurl/test_post_loop.c
+++ b/src/testcurl/test_post_loop.c
@@ -431,7 +431,7 @@ testExternalPost (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
                         MHD_OPTION_END);
diff --git a/src/testcurl/test_postform.c b/src/testcurl/test_postform.c
index bbd0d137..32809fa9 100644
--- a/src/testcurl/test_postform.c
+++ b/src/testcurl/test_postform.c
@@ -557,7 +557,7 @@ testExternalPost (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_process_arguments.c 
b/src/testcurl/test_process_arguments.c
index f9720b89..8f010057 100644
--- a/src/testcurl/test_process_arguments.c
+++ b/src/testcurl/test_process_arguments.c
@@ -149,7 +149,7 @@ testExternalGet (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
                         MHD_OPTION_END);
diff --git a/src/testcurl/test_process_headers.c 
b/src/testcurl/test_process_headers.c
index ce30b8a9..34f52d5a 100644
--- a/src/testcurl/test_process_headers.c
+++ b/src/testcurl/test_process_headers.c
@@ -406,7 +406,7 @@ testExternalGet (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL, &ahc_echo, NULL,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
                         MHD_OPTION_END);
diff --git a/src/testcurl/test_put.c b/src/testcurl/test_put.c
index 97ed8591..e321a0b4 100644
--- a/src/testcurl/test_put.c
+++ b/src/testcurl/test_put.c
@@ -398,7 +398,7 @@ testExternalPut (void)
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port,
                         NULL, NULL, &ahc_echo, &done_flag,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_put_broken_len.c 
b/src/testcurl/test_put_broken_len.c
index 65e8cd82..52a48c79 100644
--- a/src/testcurl/test_put_broken_len.c
+++ b/src/testcurl/test_put_broken_len.c
@@ -628,7 +628,7 @@ performTest (void)
   else
     port = 4220 + oneone ? 0 : 1;
 
-  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                         port, NULL, NULL,
                         &ahcCheck, &ahc_param,
                         MHD_OPTION_APP_FD_SETSIZE, (int) FD_SETSIZE,
diff --git a/src/testcurl/test_put_header_fold.c 
b/src/testcurl/test_put_header_fold.c
index 9b77ed99..ad9b7450 100644
--- a/src/testcurl/test_put_header_fold.c
+++ b/src/testcurl/test_put_header_fold.c
@@ -1147,7 +1147,7 @@ performCheck (void)
       mem_limit = (size_t) ((TEST_UPLOAD_DATA_SIZE * 4) / 3 + 2
                             + HEADERS_POINTERS_SIZE);
 
-    d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+    d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY,
                           port, NULL, NULL,
                           &ahcCheck, &ahc_param,
                           MHD_OPTION_CONNECTION_MEMORY_LIMIT, mem_limit,
diff --git a/src/testcurl/test_toolarge.c b/src/testcurl/test_toolarge.c
index e5d519c3..414f5c4f 100644
--- a/src/testcurl/test_toolarge.c
+++ b/src/testcurl/test_toolarge.c
@@ -1453,7 +1453,8 @@ startTestMhdDaemon (enum testMhdThreadsType thrType,
 
   if (testMhdThreadExternal == thrType)
     d = MHD_start_daemon (((unsigned int) thrType) | ((unsigned int) pollType)
-                          | (verbose ? MHD_USE_ERROR_LOG : 0),
+                          | (verbose ? MHD_USE_ERROR_LOG : 0)
+                          | MHD_USE_NO_THREAD_SAFETY,
                           *pport, NULL, NULL,
                           &ahcCheck, *ahc_param,
                           MHD_OPTION_URI_LOG_CALLBACK, &check_uri_cb,
diff --git a/src/testcurl/test_tricky.c b/src/testcurl/test_tricky.c
index b3f52484..8cb53a80 100644
--- a/src/testcurl/test_tricky.c
+++ b/src/testcurl/test_tricky.c
@@ -964,7 +964,8 @@ startTestMhdDaemon (enum testMhdThreadsType thrType,
 
   if (testMhdThreadExternal == thrType)
     d = MHD_start_daemon (((unsigned int) thrType) | ((unsigned int) pollType)
-                          | (verbose ? MHD_USE_ERROR_LOG : 0),
+                          | (verbose ? MHD_USE_ERROR_LOG : 0)
+                          | MHD_USE_NO_THREAD_SAFETY,
                           *pport, NULL, NULL,
                           &ahcCheck, *ahc_param,
                           MHD_OPTION_URI_LOG_CALLBACK, &check_uri_cb,
diff --git a/src/testzzuf/test_get.c b/src/testzzuf/test_get.c
index c1a245d6..a687555a 100644
--- a/src/testzzuf/test_get.c
+++ b/src/testzzuf/test_get.c
@@ -1272,9 +1272,12 @@ print_test_starting (unsigned int daemon_flags)
   else
   {
     if (0 != (MHD_USE_EPOLL & daemon_flags))
-      printf ("\nStarting test with external polling and internal 'epoll'.\n");
+      printf ("\nStarting test with%s thread safety with external polling "
+              "and internal 'epoll'.\n",
+              ((0 != (MHD_USE_NO_THREAD_SAFETY & daemon_flags)) ? "out" : ""));
     else
-      printf ("\nStarting test with external polling.\n");
+      printf ("\nStarting test with%s thread safety with external polling.\n",
+              ((0 != (MHD_USE_NO_THREAD_SAFETY & daemon_flags)) ? "out" : ""));
   }
   fflush (stdout);
 }
@@ -1623,8 +1626,9 @@ run_all_checks (void)
       if ((77 == testRes) || (99 == testRes))
         return testRes;
     }
+    testRes = testExternalPolling (&port, MHD_NO_FLAG);
   }
-  testRes = testExternalPolling (&port, MHD_NO_FLAG);
+  testRes = testExternalPolling (&port, MHD_USE_NO_THREAD_SAFETY);
   if ((77 == testRes) || (99 == testRes))
     return testRes;
   ret += testRes;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]