[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libmicrohttpd] branch master updated: Refactored threads support,
gnunet <=