commit 7764a946fd1c051dea59b0e3404a371a34319572
parent b3e48b50908ebd754da1fac9cc3b26d567413daa
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date: Thu, 16 Mar 2017 17:57:46 +0300
Fixed thread-safety of MHD_get_daemon_info() for MHD_DAEMON_INFO_CURRENT_CONNECTIONS,
Updated MHD_DAEMON_INFO_CURRENT_CONNECTIONS description
Diffstat:
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
@@ -1795,6 +1795,9 @@ enum MHD_DaemonInfoType
/**
* Request the number of current connections handled by the daemon.
* No extra arguments should be passed.
+ * Note: when using MHD in external polling mode, this type of request
+ * could be used only when #MHD_run()/#MHD_run_from_select is not
+ * working in other thread at the same time.
*/
MHD_DAEMON_INFO_CURRENT_CONNECTIONS,
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
@@ -6234,6 +6234,8 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
enum MHD_DaemonInfoType info_type,
...)
{
+ if (NULL == daemon)
+ return NULL;
switch (info_type)
{
case MHD_DAEMON_INFO_KEY_SIZE:
@@ -6247,16 +6249,20 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
#endif
case MHD_DAEMON_INFO_CURRENT_CONNECTIONS:
- MHD_cleanup_connections (daemon);
- if (daemon->worker_pool)
+ if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
+ {
+ /* Assume that MHD_run() in not called in other thread
+ * at the same time. */
+ MHD_cleanup_connections (daemon);
+ }
+ else if (daemon->worker_pool)
{
- /* Collect the connection information stored in the workers. */
unsigned int i;
-
+ /* Collect the connection information stored in the workers. */
daemon->connections = 0;
- for (i=0;i<daemon->worker_pool_size;i++)
+ for (i = 0; i < daemon->worker_pool_size; i++)
{
- MHD_cleanup_connections (&daemon->worker_pool[i]);
+ /* FIXME: next line is thread-safe only if read is atomic. */
daemon->connections += daemon->worker_pool[i].connections;
}
}