diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index e1d12645..13bd2cbf 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 }; diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 98a3a4c8..27cf3534 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c @@ -3152,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, @@ -3186,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. */ @@ -3621,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); @@ -7667,7 +7667,12 @@ MHD_start_daemon_va (unsigned int flags, return NULL; #endif /* ! UPGRADE_SUPPORT */ } -#ifndef MHD_USE_THREADS +#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 */ @@ -7707,9 +7712,9 @@ MHD_start_daemon_va (unsigned int flags, #endif } - if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) - *pflags = (*pflags & ~((enum MHD_FLAG) MHD_USE_ITC)); /* useless if we are using 'external' select */ - else + 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)) @@ -9426,12 +9431,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 4113e66d..667b6071 100644 --- a/src/microhttpd/internal.h +++ b/src/microhttpd/internal.h @@ -2551,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 @@ -2560,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