gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] branch master updated: Refactored threads support


From: gnunet
Subject: [libmicrohttpd] branch master updated: Refactored threads support
Date: Sun, 17 Sep 2023 18:58:37 +0200

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

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

The following commit(s) were added to refs/heads/master by this push:
     new 977814e1 Refactored threads support
977814e1 is described below

commit 977814e18a50b6bcbe18c14302494cf9e570a408
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Sun Sep 17 19:16:39 2023 +0300

    Refactored threads support
    
    Some platforms do not have any "invalid" value of thread handle/ID.
    Added tracking of the thread initialisation on such platforms to
    avoid accidental match with uninitialised value.
---
 src/microhttpd/connection.c           |  10 +-
 src/microhttpd/daemon.c               |  91 +++++--
 src/microhttpd/mhd_threads.c          |  76 ++++--
 src/microhttpd/mhd_threads.h          | 454 ++++++++++++++++++++++++++++------
 src/microhttpd/response.c             |   2 +-
 src/microhttpd/test_shutdown_select.c |   2 +-
 6 files changed, 522 insertions(+), 113 deletions(-)

diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 35dd96ab..b1872517 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1151,7 +1151,7 @@ MHD_connection_close_ (struct MHD_Connection *connection,
   mhd_assert (! connection->suspended);
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (connection->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (connection->tid) );
 #endif /* MHD_USE_THREADS */
   if ( (NULL != daemon->notify_completed) &&
        (connection->rq.client_aware) )
@@ -1195,7 +1195,7 @@ MHD_connection_finish_forward_ (struct MHD_Connection 
*connection)
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
                (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
 #endif /* MHD_USE_THREADS */
 
   if (0 == (daemon->options & MHD_USE_TLS))
@@ -6249,7 +6249,7 @@ cleanup_connection (struct MHD_Connection *connection)
   struct MHD_Daemon *daemon = connection->daemon;
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (connection->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (connection->tid) );
   mhd_assert (NULL == daemon->worker_pool);
 #endif /* MHD_USE_THREADS */
 
@@ -6456,7 +6456,7 @@ MHD_connection_handle_idle (struct MHD_Connection 
*connection)
   enum MHD_Result ret;
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (connection->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (connection->tid) );
 #endif /* MHD_USE_THREADS */
   /* 'daemon' is not used if epoll is not available and asserts are disabled */
   (void) daemon; /* Mute compiler warning */
@@ -7140,7 +7140,7 @@ MHD_queue_response (struct MHD_Connection *connection,
 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   if ( (! connection->suspended) &&
        (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
-       (! MHD_thread_ID_is_current_thread_ (connection->tid)) )
+       (! MHD_thread_handle_ID_is_current_thread_ (connection->tid)) )
   {
 #ifdef HAVE_MESSAGES
     MHD_DLOG (daemon,
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 209a6f86..09d58b8e 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -1171,6 +1171,13 @@ call_handlers (struct MHD_Connection *con,
   bool on_fasttrack = (con->state == MHD_CONNECTION_INIT);
   ret = MHD_YES;
 
+  mhd_assert ((0 == (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (MHD_thread_handle_ID_is_valid_ID_ (con->tid)));
+  mhd_assert ((0 != (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (! MHD_thread_handle_ID_is_valid_ID_ (con->tid)));
+  mhd_assert ((0 == (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (MHD_thread_handle_ID_is_current_thread_ (con->tid)));
+
 #ifdef HTTPS_SUPPORT
   if (con->tls_read_ready)
     read_ready = true;
@@ -1322,7 +1329,7 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
 
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (connection->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (connection->tid) );
 #endif /* MHD_USE_THREADS */
   if (daemon->shutdown)
   {
@@ -1670,7 +1677,7 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
   struct MHD_Daemon *daemon = con->daemon;
 
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (con->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (con->tid) );
   /* Here, we need to bi-directionally forward
      until the application tells us that it is done
      with the socket; */
@@ -1896,7 +1903,7 @@ thread_main_handle_connection (void *data)
   const bool use_poll = 0;
 #endif /* ! HAVE_POLL */
   bool was_suspended = false;
-  MHD_thread_init_ (&(con->tid));
+  MHD_thread_handle_ID_set_current_thread_ID_ (&(con->tid));
 
   while ( (! daemon->shutdown) &&
           (MHD_CONNECTION_CLOSED != con->state) )
@@ -2524,6 +2531,9 @@ new_connection_prepare_ (struct MHD_Daemon *daemon,
   connection->sk_nonblck = non_blck;
   connection->is_nonip = sk_is_nonip;
   connection->sk_spipe_suppress = sk_spipe_supprs;
+#ifdef MHD_USE_THREADS
+  MHD_thread_handle_ID_set_invalid_ (&connection->tid);
+#endif /* MHD_USE_THREADS */
   connection->daemon = daemon;
   connection->connection_timeout_ms = daemon->connection_timeout_ms;
   connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
@@ -2743,7 +2753,7 @@ new_connection_process_ (struct MHD_Daemon *daemon,
   /* Function manipulate connection and timeout DL-lists,
    * must be called only within daemon thread. */
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   mhd_assert (NULL == daemon->worker_pool);
 #endif /* MHD_USE_THREADS */
 
@@ -3102,7 +3112,7 @@ internal_suspend_connection_ (struct MHD_Connection 
*connection)
 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
                (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
 #endif
   if (connection->resuming)
@@ -3199,7 +3209,7 @@ MHD_suspend_connection (struct MHD_Connection *connection)
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
                (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
 #endif /* MHD_USE_THREADS */
 
   if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
@@ -3323,7 +3333,7 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   mhd_assert (NULL == daemon->worker_pool);
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
 #endif
 
   ret = MHD_NO;
@@ -3664,7 +3674,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
 
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   mhd_assert (NULL == daemon->worker_pool);
 #endif /* MHD_USE_THREADS */
 
@@ -3888,7 +3898,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
   struct MHD_Connection *pos;
 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   mhd_assert (NULL == daemon->worker_pool);
 
   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
@@ -3902,7 +3912,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
     MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
     if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
          (! pos->thread_joined) &&
-         (! MHD_join_thread_tid_ (&pos->tid)) )
+         (! MHD_thread_handle_ID_join_thread_ (pos->tid)) )
       MHD_PANIC (_ ("Failed to join a thread.\n"));
 #endif
 #ifdef UPGRADE_SUPPORT
@@ -4075,7 +4085,7 @@ MHD_get_timeout64 (struct MHD_Daemon *daemon,
 
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
 #endif /* MHD_USE_THREADS */
 
   if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
@@ -4340,6 +4350,13 @@ internal_run_from_select (struct MHD_Daemon *daemon,
                   (fd_set *) _MHD_DROP_CONST (read_fd_set))) )
     MHD_itc_clear_ (daemon->itc);
 
+  mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
+  mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
+  mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
+
   /* Process externally added connection if any */
   if (daemon->have_new)
     new_connections_list_process_ (daemon);
@@ -4693,6 +4710,13 @@ MHD_poll_all (struct MHD_Daemon *daemon,
   struct MHD_UpgradeResponseHandle *urhn;
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
 
+  mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
+  mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
+  mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
+
   if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
        (MHD_NO != resume_suspended_connections (daemon)) )
     millisec = 0;
@@ -4907,6 +4931,9 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
   int poll_itc_idx;
   MHD_socket ls;
 
+  mhd_assert (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid));
+  mhd_assert (MHD_thread_handle_ID_is_current_thread_ (daemon->tid));
+
   memset (&p,
           0,
           sizeof (p));
@@ -5070,7 +5097,7 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
 
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
 #endif /* MHD_USE_THREADS */
 
   num_events = MAX_EVENTS;
@@ -5209,6 +5236,13 @@ MHD_epoll (struct MHD_Daemon *daemon,
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   bool need_to_accept;
 
+  mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
+  mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
+  mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
+
   if (-1 == daemon->epoll_fd)
     return MHD_NO; /* we're down! */
   if (daemon->shutdown)
@@ -5569,6 +5603,8 @@ MHD_run_wait (struct MHD_Daemon *daemon,
        (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
     return MHD_NO;
 
+  mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid));
+
   if (0 > millisec)
     millisec = -1;
 #ifdef HAVE_POLL
@@ -5611,7 +5647,7 @@ close_connection (struct MHD_Connection *pos)
 
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   mhd_assert (NULL == daemon->worker_pool);
 #endif /* MHD_USE_THREADS */
 
@@ -5665,7 +5701,7 @@ MHD_polling_thread (void *cls)
   int err;
 #endif /* HAVE_PTHREAD_SIGMASK */
 
-  MHD_thread_init_ (&(daemon->tid));
+  MHD_thread_handle_ID_set_current_thread_ID_ (&(daemon->tid));
 #ifdef HAVE_PTHREAD_SIGMASK
   if ((0 == sigemptyset (&s_mask)) &&
       (0 == sigaddset (&s_mask, SIGPIPE)))
@@ -7173,6 +7209,9 @@ MHD_start_daemon_va (unsigned int flags,
   daemon->unescape_callback = &unescape_wrapper;
   daemon->connection_timeout_ms = 0;       /* no timeout */
   MHD_itc_set_invalid_ (daemon->itc);
+#ifdef MHD_USE_THREADS
+  MHD_thread_handle_ID_set_invalid_ (&daemon->tid);
+#endif /* MHD_USE_THREADS */
 #ifdef SOMAXCONN
   daemon->listen_backlog_size = SOMAXCONN;
 #else  /* !SOMAXCONN */
@@ -8175,7 +8214,7 @@ close_all_connections (struct MHD_Daemon *daemon)
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
                (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
-               MHD_thread_ID_is_current_thread_ (daemon->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   mhd_assert (NULL == daemon->worker_pool);
 #endif /* MHD_USE_THREADS */
   mhd_assert (daemon->shutdown);
@@ -8288,7 +8327,7 @@ close_all_connections (struct MHD_Daemon *daemon)
          * MHD_resume_connection() during finishing of "upgraded"
          * thread. */
         MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
-        if (! MHD_join_thread_tid_ (&pos->tid))
+        if (! MHD_thread_handle_ID_join_thread_ (pos->tid))
           MHD_PANIC (_ ("Failed to join a thread.\n"));
         pos->thread_joined = true;
         MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
@@ -8320,7 +8359,7 @@ close_all_connections (struct MHD_Daemon *daemon)
       if (! pos->thread_joined)
       {
         MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
-        if (! MHD_join_thread_tid_ (&pos->tid))
+        if (! MHD_thread_handle_ID_join_thread_ (pos->tid))
           MHD_PANIC (_ ("Failed to join a thread.\n"));
         MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
         pos->thread_joined = true;
@@ -8380,6 +8419,14 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
     return;
   if ( (daemon->shutdown) && (NULL == daemon->master) )
     MHD_PANIC (_ ("MHD_stop_daemon() was called twice."));
+
+  mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (NULL != daemon->worker_pool) || \
+              (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
+  mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) &&
+               (NULL == daemon->worker_pool)) || \
+              (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
+
   /* Slave daemons must be stopped by master daemon. */
   mhd_assert ( (NULL == daemon->master) || (daemon->shutdown) );
 
@@ -8458,7 +8505,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
         mhd_assert (false); /* Should never happen */
       }
 
-      if (! MHD_join_thread_tid_ (&daemon->tid))
+      if (! MHD_thread_handle_ID_join_thread_ (daemon->tid))
       {
         MHD_PANIC (_ ("Failed to join a thread.\n"));
       }
@@ -8556,6 +8603,14 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
 {
   if (NULL == daemon)
     return NULL;
+
+  mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
+              (NULL != daemon->worker_pool) || \
+              (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
+  mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) &&
+               (NULL == daemon->worker_pool)) || \
+              (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
+
   switch (info_type)
   {
   case MHD_DAEMON_INFO_KEY_SIZE:
diff --git a/src/microhttpd/mhd_threads.c b/src/microhttpd/mhd_threads.c
index 13cccf4c..057bf376 100644
--- a/src/microhttpd/mhd_threads.c
+++ b/src/microhttpd/mhd_threads.c
@@ -38,6 +38,7 @@
 #endif /* HAVE_PTHREAD_NP_H */
 #endif /* MHD_USE_THREAD_NAME_ */
 #include <errno.h>
+#include "mhd_assert.h"
 
 
 #ifndef MHD_USE_THREAD_NAME_
@@ -66,7 +67,7 @@
  * @return non-zero on success, zero otherwise
  */
 static int
-MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
+MHD_set_thread_name_ (const MHD_thread_ID_native_ thread_id,
                       const char *thread_name)
 {
   if (NULL == thread_name)
@@ -122,7 +123,7 @@ MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
  * @return non-zero on success, zero otherwise
  */
 static int
-MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
+MHD_set_thread_name_ (const MHD_thread_ID_native_ thread_id,
                       const char *thread_name)
 {
   static const DWORD VC_SETNAME_EXC = 0x406D1388;
@@ -164,7 +165,7 @@ MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
  * @return non-zero on success, zero otherwise
  */
 #define MHD_set_cur_thread_name_(n) \
-  MHD_set_thread_name_ ((MHD_thread_ID_) -1,(n))
+  MHD_set_thread_name_ ((MHD_thread_ID_native_) -1,(n))
 #endif /* _MSC_FULL_VER */
 #endif /* MHD_USE_W32_THREADS */
 
@@ -176,20 +177,29 @@ MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
  *
  * If thread is created, thread handle must be freed by MHD_join_thread_().
  *
- * @param thread        handle to initialize
+ * @param handle_id     handle to initialise
  * @param stack_size    size of stack for new thread, 0 for default
  * @param start_routine main function of thread
  * @param arg argument  for start_routine
  * @return non-zero on success; zero otherwise (with errno set)
  */
 int
-MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
+MHD_create_thread_ (MHD_thread_handle_ID_ *handle_id,
                     size_t stack_size,
                     MHD_THREAD_START_ROUTINE_ start_routine,
                     void *arg)
 {
 #if defined(MHD_USE_POSIX_THREADS)
   int res;
+#if defined(MHD_thread_handle_ID_get_native_handle_ptr_)
+  pthread_t *const new_tid_ptr =
+    MHD_thread_handle_ID_get_native_handle_ptr_ (handle_id);
+#else  /* ! MHD_thread_handle_ID_get_native_handle_ptr_ */
+  pthread_t new_tid;
+  pthread_t *const new_tid_ptr = &new_tid;
+#endif /* ! MHD_thread_handle_ID_get_native_handle_ptr_ */
+
+  mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (*handle_id));
 
   if (0 != stack_size)
   {
@@ -200,7 +210,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
       res = pthread_attr_setstacksize (&attr,
                                        stack_size);
       if (0 == res)
-        res = pthread_create (&(thread->handle),
+        res = pthread_create (new_tid_ptr,
                               &attr,
                               start_routine,
                               arg);
@@ -208,18 +218,28 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
     }
   }
   else
-    res = pthread_create (&(thread->handle),
+    res = pthread_create (new_tid_ptr,
                           NULL,
                           start_routine,
                           arg);
 
   if (0 != res)
+  {
     errno = res;
+    MHD_thread_handle_ID_set_invalid_ (handle_id);
+  }
+#if ! defined(MHD_thread_handle_ID_get_native_handle_ptr_)
+  else
+    MHD_thread_handle_ID_set_native_handle_ (handle_id, new_tid);
+#endif /* ! MHD_thread_handle_ID_set_current_thread_ID_ */
 
   return ! res;
 #elif defined(MHD_USE_W32_THREADS)
   uintptr_t thr_handle;
 #if SIZEOF_SIZE_T != SIZEOF_UNSIGNED_INT
+
+  mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (*handle_id));
+
   if (stack_size > UINT_MAX)
   {
     errno = EINVAL;
@@ -232,11 +252,13 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
                                            arg,
                                            0,
                                            NULL);
-  thread->handle = (MHD_thread_handle_) thr_handle;
-
-  if ((MHD_thread_handle_) 0 == thread->handle)
+  if ((MHD_thread_handle_native_) 0 == (MHD_thread_handle_native_) thr_handle)
     return 0;
 
+  MHD_thread_handle_ID_set_native_handle_ (handle_id, \
+                                           (MHD_thread_handle_native_) \
+                                           thr_handle);
+
   return ! 0;
 #endif
 }
@@ -291,7 +313,7 @@ named_thread_starter (void *data)
 /**
  * Create a named thread and set the attributes according to our options.
  *
- * @param thread        handle to initialize
+ * @param handle_id     handle to initialise
  * @param thread_name   name for new thread
  * @param stack_size    size of stack for new thread, 0 for default
  * @param start_routine main function of thread
@@ -299,7 +321,7 @@ named_thread_starter (void *data)
  * @return non-zero on success; zero otherwise (with errno set)
  */
 int
-MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
+MHD_create_named_thread_ (MHD_thread_handle_ID_ *handle_id,
                           const char *thread_name,
                           size_t stack_size,
                           MHD_THREAD_START_ROUTINE_ start_routine,
@@ -308,15 +330,22 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
 #if defined(MHD_USE_THREAD_ATTR_SETNAME)
   int res;
   pthread_attr_t attr;
+#if defined(MHD_thread_handle_ID_get_native_handle_ptr_)
+  pthread_t *const new_tid_ptr =
+    MHD_thread_handle_ID_get_native_handle_ptr_ (handle_id);
+#else  /* ! MHD_thread_handle_ID_get_native_handle_ptr_ */
+  pthread_t new_tid;
+  pthread_t *const new_tid_ptr = &new_tid;
+#endif /* ! MHD_thread_handle_ID_get_native_handle_ptr_ */
 
   res = pthread_attr_init (&attr);
   if (0 == res)
   {
 #if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD)
-    /* NetBSD use 3 arguments: second argument is string in printf-like format,
-     *                         third argument is single argument for printf;
-     * OSF1 use 3 arguments too, but last one always must be zero (NULL).
-     * MHD doesn't use '%' in thread names, so both form are used in same way.
+    /* NetBSD uses 3 arguments: second argument is string in printf-like 
format,
+     *                          third argument is single argument for printf;
+     * OSF1 uses 3 arguments too, but last one always must be zero (NULL).
+     * MHD doesn't use '%' in thread names, so both forms are used in same way.
      */
     res = pthread_attr_setname_np (&attr,
                                    thread_name,
@@ -331,14 +360,21 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
       res = pthread_attr_setstacksize (&attr,
                                        stack_size);
     if (0 == res)
-      res = pthread_create (&(thread->handle),
+      res = pthread_create (new_tid_ptr,
                             &attr,
                             start_routine,
                             arg);
     pthread_attr_destroy (&attr);
   }
   if (0 != res)
+  {
     errno = res;
+    MHD_thread_handle_ID_set_invalid_ (handle_id);
+  }
+#if ! defined(MHD_thread_handle_ID_get_native_handle_ptr_)
+  else
+    MHD_thread_handle_ID_set_native_handle_ (handle_id, new_tid);
+#endif /* ! MHD_thread_handle_ID_set_current_thread_ID_ */
 
   return ! res;
 #else  /* ! MHD_USE_THREAD_ATTR_SETNAME */
@@ -361,12 +397,16 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
   /* Set thread name in thread itself to avoid problems with
    * threads which terminated before name is set in other thread.
    */
-  if (! MHD_create_thread_ (thread,
+  if (! MHD_create_thread_ (handle_id,
                             stack_size,
                             &named_thread_starter,
                             (void *) param))
   {
+    int err_num;
+
+    err_num = errno;
     free (param);
+    errno = err_num;
     return 0;
   }
 
diff --git a/src/microhttpd/mhd_threads.h b/src/microhttpd/mhd_threads.h
index 6e1dce32..9d9b19dd 100644
--- a/src/microhttpd/mhd_threads.h
+++ b/src/microhttpd/mhd_threads.h
@@ -64,6 +64,14 @@
 #  error No threading API is available.
 #endif
 
+#ifdef HAVE_STDBOOL_H
+#  include <stdbool.h>
+#endif /* HAVE_STDBOOL_H */
+
+#if defined(MHD_USE_POSIX_THREADS) && defined(MHD_USE_W32_THREADS)
+#  error Both MHD_USE_POSIX_THREADS and MHD_USE_W32_THREADS are defined
+#endif /* MHD_USE_POSIX_THREADS && MHD_USE_W32_THREADS */
+
 #ifndef MHD_NO_THREAD_NAMES
 #  if defined(MHD_USE_POSIX_THREADS)
 #    if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \
@@ -82,26 +90,305 @@
 #  endif
 #endif
 
+/* ** Thread handle - used to control the thread ** */
+
 #if defined(MHD_USE_POSIX_THREADS)
-typedef pthread_t MHD_thread_handle_;
+/**
+ * Wait until specified thread is ended and free thread handle on success.
+ * @param thread handle to watch
+ * @return nonzero on success, zero otherwise
+ */
+#  define MHD_join_thread_(native_handle) \
+  (! pthread_join ((native_handle), NULL))
 #elif defined(MHD_USE_W32_THREADS)
-typedef HANDLE MHD_thread_handle_;
+/**
+ * Wait until specified thread is ended and free thread handle on success.
+ * @param thread handle to watch
+ * @return nonzero on success, zero otherwise
+ */
+#  define MHD_join_thread_(native_handle) \
+  ( (WAIT_OBJECT_0 == WaitForSingleObject ( (native_handle), INFINITE)) ? \
+    (CloseHandle ( (native_handle)), ! 0) : 0 )
 #endif
 
 #if defined(MHD_USE_POSIX_THREADS)
-#  define MHD_THRD_RTRN_TYPE_ void*
-#  define MHD_THRD_CALL_SPEC_
+/**
+ * The native type to control the thread from other threads
+ */
+typedef pthread_t MHD_thread_handle_native_;
 #elif defined(MHD_USE_W32_THREADS)
-#  define MHD_THRD_RTRN_TYPE_ unsigned
-#  define MHD_THRD_CALL_SPEC_ __stdcall
+/**
+ * The native type to control the thread from other threads
+ */
+typedef HANDLE MHD_thread_handle_native_;
 #endif
 
 #if defined(MHD_USE_POSIX_THREADS)
-typedef pthread_t MHD_thread_ID_;
+#  if defined(__gnu_linux__) || \
+  (defined(__linux__) && defined(__GLIBC__))
+/* The next part of code is disabled because it relies on undocumented
+   behaviour.
+   It could be enabled for neglectable performance and size improvements. */
+#  if 0 /* Disabled code */
+/**
+ * The native invalid value for native thread handle
+ */
+#    define MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ \
+     ((MHD_thread_handle_native_) 0)
+#  endif /* Disabled code */
+#  endif /* __gnu_linux__ || (__linux__ && __GLIBC__) */
 #elif defined(MHD_USE_W32_THREADS)
-typedef DWORD MHD_thread_ID_;
+/**
+ * The native invalid value for native thread handle
+ */
+#  define MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ \
+  ((MHD_thread_handle_native_) NULL)
+#endif /* MHD_USE_W32_THREADS */
+
+#if ! defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_)
+/**
+ * Structure with thread handle and validity flag
+ */
+struct MHD_thread_handle_struct_
+{
+  bool valid;                       /**< true if native handle is set */
+  MHD_thread_handle_native_ native; /**< the native thread handle */
+};
+/**
+ * Type with thread handle that can be set to invalid value
+ */
+typedef struct MHD_thread_handle_struct_ MHD_thread_handle_;
+
+/**
+ * Set variable pointed by @a handle_ptr to invalid (unset) value
+ */
+#  define MHD_thread_handle_set_invalid_(handle_ptr) \
+   ((handle_ptr)->valid = false)
+/**
+ * Set native handle in variable pointed by @a handle_ptr
+ * to @a native_val value
+ */
+#  define MHD_thread_handle_set_native_(handle_ptr,native_val) \
+   ((handle_ptr)->valid = true, (handle_ptr)->native = native_val)
+/**
+ * Check whether native handle value is set in @a handle_var variable
+ */
+#  define MHD_thread_handle_is_valid_(handle_var) \
+   ((handle_var).valid)
+/**
+ * Get native handle value from @a handle_var variable
+ */
+#  define MHD_thread_handle_get_native_(handle_var) \
+   ((handle_var).native)
+#else  /* MHD_THREAD_HANDLE_NATIVE_INVALID_ */
+/**
+ * Type with thread handle that can be set to invalid value
+ */
+typedef MHD_thread_handle_native_ MHD_thread_handle_;
+
+/**
+ * Set variable pointed by @a handle_ptr to invalid (unset) value
+ */
+#  define MHD_thread_handle_set_invalid_(handle_ptr) \
+    ((*(handle_ptr)) = MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_)
+/**
+ * Set native handle in the variable pointed by @a handle_ptr
+ * to @a native_val value
+ */
+#  define MHD_thread_handle_set_native_(handle_ptr,native_val) \
+    ((*(handle_ptr)) = native_val)
+/**
+ * Check whether native handle value is set in @a handle_var variable
+ */
+#  define MHD_thread_handle_is_valid_(handle_var) \
+    (MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ != handle_var)
+/**
+ * Get native handle value from @a handle_var variable
+ */
+#  define MHD_thread_handle_get_native_(handle_var) \
+    (handle_var)
+/**
+ * Get pointer to native handle stored the variable pointed by @a handle_ptr
+ * @note This macro could not available if direct manipulation of
+ *       the native handle is not possible
+ */
+#  define MHD_thread_handle_get_native_ptr_(handle_ptr) \
+    (handle_ptr)
+#endif /* MHD_THREAD_HANDLE_NATIVE_INVALID_ */
+
+
+/* ** Thread ID - used to check threads match ** */
+
+#if defined(MHD_USE_POSIX_THREADS)
+/**
+ * The native type used to check whether current thread matches expected thread
+ */
+typedef pthread_t MHD_thread_ID_native_;
+
+/**
+ * Function to get the current thread native ID.
+ */
+#  define MHD_thread_ID_native_current_ pthread_self
+
+/**
+ * Check whether two native thread IDs are equal.
+ * @return non-zero if equal, zero if not equal
+ */
+#  define MHD_thread_ID_native_equal_(id1,id2) \
+  (pthread_equal(id1,id2))
+#elif defined(MHD_USE_W32_THREADS)
+/**
+ * The native type used to check whether current thread matches expected thread
+ */
+typedef DWORD MHD_thread_ID_native_;
+
+/**
+ * Function to get the current thread native ID.
+ */
+#  define MHD_thread_ID_native_current_ GetCurrentThreadId
+
+/**
+ * Check whether two native thread IDs are equal.
+ * @return non-zero if equal, zero if not equal
+ */
+#  define MHD_thread_ID_native_equal_(id1,id2) \
+  ((id1) == (id2))
 #endif
 
+/**
+ * Check whether specified thread ID matches current thread.
+ * @param id the thread ID to match
+ * @return nonzero on match, zero otherwise
+ */
+#define MHD_thread_ID_native_is_current_thread_(id) \
+    MHD_thread_ID_native_equal_(id, MHD_thread_ID_native_current_())
+
+
+#if defined(MHD_USE_POSIX_THREADS)
+#  if defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_)
+/**
+ * The native invalid value for native thread ID
+ */
+#    define MHD_THREAD_ID_NATIVE_VALUE_INVALID_ \
+            MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_
+#  endif /* MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ */
+#elif defined(MHD_USE_W32_THREADS)
+/**
+ * The native invalid value for native thread ID
+ */
+ #  define MHD_THREAD_ID_NATIVE_VALUE_INVALID_ \
+   ((MHD_thread_ID_native_) 0)
+#endif /* MHD_USE_W32_THREADS */
+
+#if ! defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_)
+/**
+ * Structure with thread id and validity flag
+ */
+struct MHD_thread_ID_struct_
+{
+  bool valid;                   /**< true if native ID is set */
+  MHD_thread_ID_native_ native; /**< the native thread ID */
+};
+/**
+ * Type with thread ID that can be set to invalid value
+ */
+typedef struct MHD_thread_ID_struct_ MHD_thread_ID_;
+
+/**
+ * Set variable pointed by @a ID_ptr to invalid (unset) value
+ */
+#  define MHD_thread_ID_set_invalid_(ID_ptr) \
+   ((ID_ptr)->valid = false)
+/**
+ * Set native ID in variable pointed by @a ID_ptr
+ * to @a native_val value
+ */
+#  define MHD_thread_ID_set_native_(ID_ptr,native_val) \
+   ((ID_ptr)->valid = true, (ID_ptr)->native = native_val)
+/**
+ * Check whether native ID value is set in @a ID_var variable
+ */
+#  define MHD_thread_ID_is_valid_(ID_var) \
+   ((ID_var).valid)
+/**
+ * Get native ID value from @a ID_var variable
+ */
+#  define MHD_thread_ID_get_native_(ID_var) \
+    ((ID_var).native)
+/**
+ * Check whether @a ID_var variable is equal current thread
+ */
+#  define MHD_thread_ID_is_current_thread_(ID_var) \
+    (MHD_thread_ID_is_valid_(ID_var) && \
+     MHD_thread_ID_native_is_current_thread_((ID_var).native))
+#else  /* MHD_THREAD_ID_NATIVE_INVALID_ */
+/**
+ * Type with thread ID that can be set to invalid value
+ */
+typedef MHD_thread_ID_native_ MHD_thread_ID_;
+
+/**
+ * Set variable pointed by @a ID_ptr to invalid (unset) value
+ */
+#  define MHD_thread_ID_set_invalid_(ID_ptr) \
+    ((*(ID_ptr)) = MHD_THREAD_ID_NATIVE_VALUE_INVALID_)
+/**
+ * Set native ID in variable pointed by @a ID_ptr
+ * to @a native_val value
+ */
+#  define MHD_thread_ID_set_native_(ID_ptr,native_val) \
+    ((*(ID_ptr)) = native_val)
+/**
+ * Check whether native ID value is set in @a ID_var variable
+ */
+#  define MHD_thread_ID_is_valid_(ID_var) \
+    (MHD_THREAD_ID_NATIVE_VALUE_INVALID_ != ID_var)
+/**
+ * Get native ID value from @a ID_var variable
+ */
+#  define MHD_thread_ID_get_native_(ID_var) \
+    (ID_var)
+/**
+ * Check whether @a ID_var variable is equal current thread
+ */
+#  define MHD_thread_ID_is_current_thread_(ID_var) \
+    MHD_thread_ID_native_is_current_thread_(ID_var)
+#endif /* MHD_THREAD_ID_NATIVE_INVALID_ */
+
+/**
+ * Set current thread ID in variable pointed by @a ID_ptr
+ */
+#  define MHD_thread_ID_set_current_thread_(ID_ptr) \
+    MHD_thread_ID_set_native_(ID_ptr,MHD_thread_ID_native_current_())
+
+
+#if defined(MHD_USE_POSIX_THREADS)
+#  if defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) && \
+  ! defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_)
+#    error \
+  MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is defined, but 
MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is not defined
+#  elif ! defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) && \
+  defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_)
+#    error \
+  MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is not defined, but 
MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is defined
+#  endif
+#endif /* MHD_USE_POSIX_THREADS */
+
+/* When staring a new thread, the kernel (and thread implementation) may
+ * pause the calling (initial) thread and start the new thread.
+ * If thread identifier is assigned to variable in the initial thread then
+ * the value of the identifier variable will be undefined in the new thread
+ * until the initial thread continue processing.
+ * However, it is also possible that the new thread created, but not executed
+ * for some time while the initial thread continue execution. In this case any
+ * variable assigned in the new thread will be undefined for some time until
+ * they really processed by the new thread.
+ * To avoid data races, a special structure MHD_thread_handle_ID_ is used.
+ * The "handle" is assigned by calling (initial) thread and should be always
+ * defined when checked in the initial thread.
+ * The "ID" is assigned by the new thread and should be always defined when
+ * checked inside the new thread.
+ */
 /* Depending on implementation, pthread_create() MAY set thread ID into
  * provided pointer and after it start thread OR start thread and after
  * it set thread ID. In the latter case, to avoid data races, additional
@@ -109,95 +396,122 @@ typedef DWORD MHD_thread_ID_;
  * is known for setting thread ID BEFORE starting thread macro
  * MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD could be defined
  * to save some resources. */
+/* #define MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD 1 */
+
 /* * handle - must be valid when other thread knows that particular thread
      is started.
    * ID     - must be valid when code is executed inside thread */
-#if defined(MHD_USE_POSIX_THREADS)
-#  ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
+#if defined(MHD_USE_POSIX_THREADS) && \
+  defined(MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD) && \
+  defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) && \
+  defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_) && \
+  defined(MHD_thread_handle_get_native_ptr_)
 union _MHD_thread_handle_ID_
 {
   MHD_thread_handle_ handle;    /**< To be used in other threads */
-  MHD_thread_ID_ ID;            /**< To be used in thread itself */
+  MHD_thread_ID_ ID;            /**< To be used in the thread itself */
 };
 typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
-#  else  /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
-struct _MHD_thread_handle_ID_
-{
-  MHD_thread_handle_ handle;    /**< To be used in other threads */
-  MHD_thread_ID_ ID;            /**< To be used in thread itself */
-};
-typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
-#  endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
-#elif defined(MHD_USE_W32_THREADS)
+#  define MHD_THREAD_HANDLE_ID_IS_UNION 1
+#else  /* !MHD_USE_POSIX_THREADS
+          || !MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
+          || !MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_
+          || !MHD_THREAD_ID_NATIVE_VALUE_INVALID_
+          || !MHD_thread_handle_get_native_ptr_ */
 struct _MHD_thread_handle_ID_
 {
   MHD_thread_handle_ handle;    /**< To be used in other threads */
-  MHD_thread_ID_ ID;            /**< To be used in thread itself */
+  MHD_thread_ID_ ID;            /**< To be used in the thread itself */
 };
 typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
-#endif
+#endif /* !MHD_USE_POSIX_THREADS
+          || !MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
+          || !MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_
+          || !MHD_THREAD_ID_NATIVE_VALUE_INVALID_
+          || !MHD_thread_handle_get_native_ptr_ */
 
-#if defined(MHD_USE_POSIX_THREADS)
 /**
- * Wait until specified thread is ended and free thread handle on success.
- * @param thread handle to watch
- * @return nonzero on success, zero otherwise
+ * Set MHD_thread_handle_ID_ to invalid value
  */
-#define MHD_join_thread_(thread) (! pthread_join ((thread), NULL))
-#elif defined(MHD_USE_W32_THREADS)
+#define MHD_thread_handle_ID_set_invalid_(hndl_id_ptr) \
+  (MHD_thread_handle_set_invalid_(&((hndl_id_ptr)->handle)), \
+   MHD_thread_ID_set_invalid_(&((hndl_id_ptr)->ID)))
+
 /**
- * Wait until specified thread is ended and free thread handle on success.
- * @param thread handle to watch
- * @return nonzero on success, zero otherwise
+ * Check whether thread handle is valid.
+ * To be used in threads other then the thread specified by @a hndl_id.
  */
-#define MHD_join_thread_(thread) \
-  ( (WAIT_OBJECT_0 == WaitForSingleObject ( (thread), INFINITE)) ? \
-    (CloseHandle ( (thread)), ! 0) : 0 )
-#endif
+#define MHD_thread_handle_ID_is_valid_handle_(hndl_id) \
+    MHD_thread_handle_is_valid_((hndl_id).handle)
 
-#define MHD_join_thread_tid_(thread_handle_ID_ptr) \
-  (MHD_join_thread_((thread_handle_ID_ptr)->handle))
+/**
+ * Set native handle in variable pointed by @a hndl_id_ptr
+ * to @a native_val value
+ */
+#define MHD_thread_handle_ID_set_native_handle_(hndl_id_ptr,native_val) \
+    MHD_thread_handle_set_native_(&((hndl_id_ptr)->handle),native_val)
 
-#if defined(MHD_USE_POSIX_THREADS)
+#if defined(MHD_thread_handle_get_native_ptr_)
 /**
- * Check whether provided thread ID matches current thread.
- * @param ID thread ID to match
- * @return nonzero on match, zero otherwise
+ * Get pointer to native handle stored the variable pointed by @a hndl_id_ptr
+ * @note This macro could not available if direct manipulation of
+ *       the native handle is not possible
  */
-#  define MHD_thread_ID_is_current_thread_(tid) \
-     (pthread_equal ((tid).ID, pthread_self ()))
-#elif defined(MHD_USE_W32_THREADS)
+#  define MHD_thread_handle_ID_get_native_handle_ptr_(hndl_id_ptr) \
+    MHD_thread_handle_get_native_ptr_(&((hndl_id_ptr)->handle))
+#endif /* MHD_thread_handle_get_native_ptr_ */
+
 /**
- * Check whether provided thread ID matches current thread.
- * @param ID thread ID to match
- * @return nonzero on match, zero otherwise
+ * Get native thread handle from MHD_thread_handle_ID_ variable.
  */
-#  define MHD_thread_ID_is_current_thread_(tid) \
-     (GetCurrentThreadId () == (tid).ID)
-#endif
+#define MHD_thread_handle_ID_get_native_handle_(hndl_id) \
+    MHD_thread_handle_get_native_((hndl_id).handle)
 
-#if defined(MHD_USE_POSIX_THREADS)
-#  ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
 /**
- * Initialise thread ID.
- * @param thread_handle_ID_ptr pointer to thread handle-ID
+ * Check whether thread ID is valid.
+ * To be used in the thread itself.
+ */
+#define MHD_thread_handle_ID_is_valid_ID_(hndl_id) \
+    MHD_thread_ID_is_valid_((hndl_id).ID)
+
+#if defined(MHD_THREAD_HANDLE_ID_IS_UNION)
+#  if defined(MHD_USE_W32_THREADS)
+#    error MHD_thread_handle_ID_ cannot be a union with W32 threads
+#  endif /* MHD_USE_W32_THREADS */
+/**
+ * Set current thread ID in the variable pointed by @a hndl_id_ptr
  */
-#define MHD_thread_init_(thread_handle_ID_ptr) (void) 0
-#  else  /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
+#  define MHD_thread_handle_ID_set_current_thread_ID_(hndl_id_ptr) (void) 0
+#else  /* ! MHD_THREAD_HANDLE_ID_IS_UNION */
 /**
- * Initialise thread ID.
- * @param thread_handle_ID_ptr pointer to thread handle-ID
+ * Set current thread ID in the variable pointed by @a hndl_id_ptr
  */
-#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \
-                                                  pthread_self ())
-#  endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
-#elif defined(MHD_USE_W32_THREADS)
+#  define MHD_thread_handle_ID_set_current_thread_ID_(hndl_id_ptr) \
+    MHD_thread_ID_set_current_thread_(&((hndl_id_ptr)->ID))
+#endif /* ! MHD_THREAD_HANDLE_ID_IS_UNION */
+
+/**
+ * Check whether provided thread ID matches current thread.
+ * @param ID thread ID to match
+ * @return nonzero on match, zero otherwise
+ */
+#define MHD_thread_handle_ID_is_current_thread_(hndl_id) \
+     MHD_thread_ID_is_current_thread_((hndl_id).ID)
+
 /**
- * Initialise thread ID.
- * @param thread_handle_ID_ptr pointer to thread handle-ID
+ * Wait until specified thread is ended and free thread handle on success.
+ * @param hndl_id_ handle with ID to watch
+ * @return nonzero on success, zero otherwise
  */
-#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \
-                                                  GetCurrentThreadId ())
+#define MHD_thread_handle_ID_join_thread_(hndl_id) \
+  MHD_join_thread_(MHD_thread_handle_ID_get_native_handle_(hndl_id))
+
+#if defined(MHD_USE_POSIX_THREADS)
+#  define MHD_THRD_RTRN_TYPE_ void*
+#  define MHD_THRD_CALL_SPEC_
+#elif defined(MHD_USE_W32_THREADS)
+#  define MHD_THRD_RTRN_TYPE_ unsigned
+#  define MHD_THRD_CALL_SPEC_ __stdcall
 #endif
 
 /**
@@ -215,14 +529,14 @@ typedef MHD_THRD_RTRN_TYPE_
  *
  * If thread is created, thread handle must be freed by MHD_join_thread_().
  *
- * @param thread        handle to initialize
+ * @param handle_id     handle to initialise
  * @param stack_size    size of stack for new thread, 0 for default
  * @param start_routine main function of thread
  * @param arg argument  for start_routine
  * @return non-zero on success; zero otherwise (with errno set)
  */
 int
-MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
+MHD_create_thread_ (MHD_thread_handle_ID_ *handle_id,
                     size_t stack_size,
                     MHD_THREAD_START_ROUTINE_ start_routine,
                     void *arg);
@@ -233,7 +547,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
 /**
  * Create a named thread and set the attributes according to our options.
  *
- * @param thread        handle to initialize
+ * @param handle_id     handle to initialise
  * @param thread_name   name for new thread
  * @param stack_size    size of stack for new thread, 0 for default
  * @param start_routine main function of thread
@@ -241,7 +555,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
  * @return non-zero on success; zero otherwise
  */
 int
-MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
+MHD_create_named_thread_ (MHD_thread_handle_ID_ *handle_id,
                           const char *thread_name,
                           size_t stack_size,
                           MHD_THREAD_START_ROUTINE_ start_routine,
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 8cd540b1..e96bf0d8 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -1941,7 +1941,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response 
*response,
 
 #ifdef MHD_USE_THREADS
   mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
-               MHD_thread_ID_is_current_thread_ (connection->tid) );
+               MHD_thread_handle_ID_is_current_thread_ (connection->tid) );
 #endif /* MHD_USE_THREADS */
 
   /* "Upgrade" responses accepted only if MHD_ALLOW_UPGRADE is enabled */
diff --git a/src/microhttpd/test_shutdown_select.c 
b/src/microhttpd/test_shutdown_select.c
index 9f68fd05..8bdafde7 100644
--- a/src/microhttpd/test_shutdown_select.c
+++ b/src/microhttpd/test_shutdown_select.c
@@ -322,7 +322,7 @@ main (int argc, char *const *argv)
    */
   for (i = 0; i < 5 && result == 0; i++)
   {
-    MHD_thread_handle_ sel_thrd;
+    MHD_thread_handle_native_ sel_thrd;
     /* fprintf(stdout, "Creating, binding and listening socket...\n"); */
     MHD_socket listen_socket = start_socket_listen (AF_INET);
     if (MHD_INVALID_SOCKET == listen_socket)

-- 
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]