diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-09-17 19:16:39 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-09-17 19:57:56 +0300 |
commit | 977814e18a50b6bcbe18c14302494cf9e570a408 (patch) | |
tree | 62911975077037841a47176723343153f23cda61 | |
parent | 580814314f09b8e73f7641264998320a9694a459 (diff) | |
download | libmicrohttpd-977814e18a50b6bcbe18c14302494cf9e570a408.tar.gz libmicrohttpd-977814e18a50b6bcbe18c14302494cf9e570a408.zip |
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.
-rw-r--r-- | src/microhttpd/connection.c | 10 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 91 | ||||
-rw-r--r-- | src/microhttpd/mhd_threads.c | 76 | ||||
-rw-r--r-- | src/microhttpd/mhd_threads.h | 454 | ||||
-rw-r--r-- | src/microhttpd/response.c | 2 | ||||
-rw-r--r-- | 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, | |||
1151 | mhd_assert (! connection->suspended); | 1151 | mhd_assert (! connection->suspended); |
1152 | #ifdef MHD_USE_THREADS | 1152 | #ifdef MHD_USE_THREADS |
1153 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 1153 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
1154 | MHD_thread_ID_is_current_thread_ (connection->tid) ); | 1154 | MHD_thread_handle_ID_is_current_thread_ (connection->tid) ); |
1155 | #endif /* MHD_USE_THREADS */ | 1155 | #endif /* MHD_USE_THREADS */ |
1156 | if ( (NULL != daemon->notify_completed) && | 1156 | if ( (NULL != daemon->notify_completed) && |
1157 | (connection->rq.client_aware) ) | 1157 | (connection->rq.client_aware) ) |
@@ -1195,7 +1195,7 @@ MHD_connection_finish_forward_ (struct MHD_Connection *connection) | |||
1195 | #ifdef MHD_USE_THREADS | 1195 | #ifdef MHD_USE_THREADS |
1196 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 1196 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
1197 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \ | 1197 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \ |
1198 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 1198 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
1199 | #endif /* MHD_USE_THREADS */ | 1199 | #endif /* MHD_USE_THREADS */ |
1200 | 1200 | ||
1201 | if (0 == (daemon->options & MHD_USE_TLS)) | 1201 | if (0 == (daemon->options & MHD_USE_TLS)) |
@@ -6249,7 +6249,7 @@ cleanup_connection (struct MHD_Connection *connection) | |||
6249 | struct MHD_Daemon *daemon = connection->daemon; | 6249 | struct MHD_Daemon *daemon = connection->daemon; |
6250 | #ifdef MHD_USE_THREADS | 6250 | #ifdef MHD_USE_THREADS |
6251 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 6251 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
6252 | MHD_thread_ID_is_current_thread_ (connection->tid) ); | 6252 | MHD_thread_handle_ID_is_current_thread_ (connection->tid) ); |
6253 | mhd_assert (NULL == daemon->worker_pool); | 6253 | mhd_assert (NULL == daemon->worker_pool); |
6254 | #endif /* MHD_USE_THREADS */ | 6254 | #endif /* MHD_USE_THREADS */ |
6255 | 6255 | ||
@@ -6456,7 +6456,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) | |||
6456 | enum MHD_Result ret; | 6456 | enum MHD_Result ret; |
6457 | #ifdef MHD_USE_THREADS | 6457 | #ifdef MHD_USE_THREADS |
6458 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 6458 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
6459 | MHD_thread_ID_is_current_thread_ (connection->tid) ); | 6459 | MHD_thread_handle_ID_is_current_thread_ (connection->tid) ); |
6460 | #endif /* MHD_USE_THREADS */ | 6460 | #endif /* MHD_USE_THREADS */ |
6461 | /* 'daemon' is not used if epoll is not available and asserts are disabled */ | 6461 | /* 'daemon' is not used if epoll is not available and asserts are disabled */ |
6462 | (void) daemon; /* Mute compiler warning */ | 6462 | (void) daemon; /* Mute compiler warning */ |
@@ -7140,7 +7140,7 @@ MHD_queue_response (struct MHD_Connection *connection, | |||
7140 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 7140 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
7141 | if ( (! connection->suspended) && | 7141 | if ( (! connection->suspended) && |
7142 | (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) && | 7142 | (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) && |
7143 | (! MHD_thread_ID_is_current_thread_ (connection->tid)) ) | 7143 | (! MHD_thread_handle_ID_is_current_thread_ (connection->tid)) ) |
7144 | { | 7144 | { |
7145 | #ifdef HAVE_MESSAGES | 7145 | #ifdef HAVE_MESSAGES |
7146 | MHD_DLOG (daemon, | 7146 | 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, | |||
1171 | bool on_fasttrack = (con->state == MHD_CONNECTION_INIT); | 1171 | bool on_fasttrack = (con->state == MHD_CONNECTION_INIT); |
1172 | ret = MHD_YES; | 1172 | ret = MHD_YES; |
1173 | 1173 | ||
1174 | mhd_assert ((0 == (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
1175 | (MHD_thread_handle_ID_is_valid_ID_ (con->tid))); | ||
1176 | mhd_assert ((0 != (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
1177 | (! MHD_thread_handle_ID_is_valid_ID_ (con->tid))); | ||
1178 | mhd_assert ((0 == (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
1179 | (MHD_thread_handle_ID_is_current_thread_ (con->tid))); | ||
1180 | |||
1174 | #ifdef HTTPS_SUPPORT | 1181 | #ifdef HTTPS_SUPPORT |
1175 | if (con->tls_read_ready) | 1182 | if (con->tls_read_ready) |
1176 | read_ready = true; | 1183 | read_ready = true; |
@@ -1322,7 +1329,7 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1322 | 1329 | ||
1323 | #ifdef MHD_USE_THREADS | 1330 | #ifdef MHD_USE_THREADS |
1324 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 1331 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
1325 | MHD_thread_ID_is_current_thread_ (connection->tid) ); | 1332 | MHD_thread_handle_ID_is_current_thread_ (connection->tid) ); |
1326 | #endif /* MHD_USE_THREADS */ | 1333 | #endif /* MHD_USE_THREADS */ |
1327 | if (daemon->shutdown) | 1334 | if (daemon->shutdown) |
1328 | { | 1335 | { |
@@ -1670,7 +1677,7 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
1670 | struct MHD_Daemon *daemon = con->daemon; | 1677 | struct MHD_Daemon *daemon = con->daemon; |
1671 | 1678 | ||
1672 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 1679 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
1673 | MHD_thread_ID_is_current_thread_ (con->tid) ); | 1680 | MHD_thread_handle_ID_is_current_thread_ (con->tid) ); |
1674 | /* Here, we need to bi-directionally forward | 1681 | /* Here, we need to bi-directionally forward |
1675 | until the application tells us that it is done | 1682 | until the application tells us that it is done |
1676 | with the socket; */ | 1683 | with the socket; */ |
@@ -1896,7 +1903,7 @@ thread_main_handle_connection (void *data) | |||
1896 | const bool use_poll = 0; | 1903 | const bool use_poll = 0; |
1897 | #endif /* ! HAVE_POLL */ | 1904 | #endif /* ! HAVE_POLL */ |
1898 | bool was_suspended = false; | 1905 | bool was_suspended = false; |
1899 | MHD_thread_init_ (&(con->tid)); | 1906 | MHD_thread_handle_ID_set_current_thread_ID_ (&(con->tid)); |
1900 | 1907 | ||
1901 | while ( (! daemon->shutdown) && | 1908 | while ( (! daemon->shutdown) && |
1902 | (MHD_CONNECTION_CLOSED != con->state) ) | 1909 | (MHD_CONNECTION_CLOSED != con->state) ) |
@@ -2524,6 +2531,9 @@ new_connection_prepare_ (struct MHD_Daemon *daemon, | |||
2524 | connection->sk_nonblck = non_blck; | 2531 | connection->sk_nonblck = non_blck; |
2525 | connection->is_nonip = sk_is_nonip; | 2532 | connection->is_nonip = sk_is_nonip; |
2526 | connection->sk_spipe_suppress = sk_spipe_supprs; | 2533 | connection->sk_spipe_suppress = sk_spipe_supprs; |
2534 | #ifdef MHD_USE_THREADS | ||
2535 | MHD_thread_handle_ID_set_invalid_ (&connection->tid); | ||
2536 | #endif /* MHD_USE_THREADS */ | ||
2527 | connection->daemon = daemon; | 2537 | connection->daemon = daemon; |
2528 | connection->connection_timeout_ms = daemon->connection_timeout_ms; | 2538 | connection->connection_timeout_ms = daemon->connection_timeout_ms; |
2529 | connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ; | 2539 | connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ; |
@@ -2743,7 +2753,7 @@ new_connection_process_ (struct MHD_Daemon *daemon, | |||
2743 | /* Function manipulate connection and timeout DL-lists, | 2753 | /* Function manipulate connection and timeout DL-lists, |
2744 | * must be called only within daemon thread. */ | 2754 | * must be called only within daemon thread. */ |
2745 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 2755 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
2746 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 2756 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
2747 | mhd_assert (NULL == daemon->worker_pool); | 2757 | mhd_assert (NULL == daemon->worker_pool); |
2748 | #endif /* MHD_USE_THREADS */ | 2758 | #endif /* MHD_USE_THREADS */ |
2749 | 2759 | ||
@@ -3102,7 +3112,7 @@ internal_suspend_connection_ (struct MHD_Connection *connection) | |||
3102 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3112 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3103 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 3113 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
3104 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \ | 3114 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \ |
3105 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 3115 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
3106 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 3116 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
3107 | #endif | 3117 | #endif |
3108 | if (connection->resuming) | 3118 | if (connection->resuming) |
@@ -3199,7 +3209,7 @@ MHD_suspend_connection (struct MHD_Connection *connection) | |||
3199 | #ifdef MHD_USE_THREADS | 3209 | #ifdef MHD_USE_THREADS |
3200 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 3210 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
3201 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \ | 3211 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \ |
3202 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 3212 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
3203 | #endif /* MHD_USE_THREADS */ | 3213 | #endif /* MHD_USE_THREADS */ |
3204 | 3214 | ||
3205 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) | 3215 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) |
@@ -3323,7 +3333,7 @@ resume_suspended_connections (struct MHD_Daemon *daemon) | |||
3323 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3333 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3324 | mhd_assert (NULL == daemon->worker_pool); | 3334 | mhd_assert (NULL == daemon->worker_pool); |
3325 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 3335 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
3326 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 3336 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
3327 | #endif | 3337 | #endif |
3328 | 3338 | ||
3329 | ret = MHD_NO; | 3339 | ret = MHD_NO; |
@@ -3664,7 +3674,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
3664 | 3674 | ||
3665 | #ifdef MHD_USE_THREADS | 3675 | #ifdef MHD_USE_THREADS |
3666 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 3676 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
3667 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 3677 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
3668 | mhd_assert (NULL == daemon->worker_pool); | 3678 | mhd_assert (NULL == daemon->worker_pool); |
3669 | #endif /* MHD_USE_THREADS */ | 3679 | #endif /* MHD_USE_THREADS */ |
3670 | 3680 | ||
@@ -3888,7 +3898,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
3888 | struct MHD_Connection *pos; | 3898 | struct MHD_Connection *pos; |
3889 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3899 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3890 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 3900 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
3891 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 3901 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
3892 | mhd_assert (NULL == daemon->worker_pool); | 3902 | mhd_assert (NULL == daemon->worker_pool); |
3893 | 3903 | ||
3894 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 3904 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
@@ -3902,7 +3912,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
3902 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 3912 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
3903 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 3913 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
3904 | (! pos->thread_joined) && | 3914 | (! pos->thread_joined) && |
3905 | (! MHD_join_thread_tid_ (&pos->tid)) ) | 3915 | (! MHD_thread_handle_ID_join_thread_ (pos->tid)) ) |
3906 | MHD_PANIC (_ ("Failed to join a thread.\n")); | 3916 | MHD_PANIC (_ ("Failed to join a thread.\n")); |
3907 | #endif | 3917 | #endif |
3908 | #ifdef UPGRADE_SUPPORT | 3918 | #ifdef UPGRADE_SUPPORT |
@@ -4075,7 +4085,7 @@ MHD_get_timeout64 (struct MHD_Daemon *daemon, | |||
4075 | 4085 | ||
4076 | #ifdef MHD_USE_THREADS | 4086 | #ifdef MHD_USE_THREADS |
4077 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 4087 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
4078 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 4088 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
4079 | #endif /* MHD_USE_THREADS */ | 4089 | #endif /* MHD_USE_THREADS */ |
4080 | 4090 | ||
4081 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 4091 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
@@ -4340,6 +4350,13 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
4340 | (fd_set *) _MHD_DROP_CONST (read_fd_set))) ) | 4350 | (fd_set *) _MHD_DROP_CONST (read_fd_set))) ) |
4341 | MHD_itc_clear_ (daemon->itc); | 4351 | MHD_itc_clear_ (daemon->itc); |
4342 | 4352 | ||
4353 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
4354 | (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); | ||
4355 | mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
4356 | (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); | ||
4357 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
4358 | (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); | ||
4359 | |||
4343 | /* Process externally added connection if any */ | 4360 | /* Process externally added connection if any */ |
4344 | if (daemon->have_new) | 4361 | if (daemon->have_new) |
4345 | new_connections_list_process_ (daemon); | 4362 | new_connections_list_process_ (daemon); |
@@ -4693,6 +4710,13 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
4693 | struct MHD_UpgradeResponseHandle *urhn; | 4710 | struct MHD_UpgradeResponseHandle *urhn; |
4694 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 4711 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
4695 | 4712 | ||
4713 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
4714 | (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); | ||
4715 | mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
4716 | (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); | ||
4717 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
4718 | (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); | ||
4719 | |||
4696 | if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && | 4720 | if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && |
4697 | (MHD_NO != resume_suspended_connections (daemon)) ) | 4721 | (MHD_NO != resume_suspended_connections (daemon)) ) |
4698 | millisec = 0; | 4722 | millisec = 0; |
@@ -4907,6 +4931,9 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon, | |||
4907 | int poll_itc_idx; | 4931 | int poll_itc_idx; |
4908 | MHD_socket ls; | 4932 | MHD_socket ls; |
4909 | 4933 | ||
4934 | mhd_assert (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)); | ||
4935 | mhd_assert (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)); | ||
4936 | |||
4910 | memset (&p, | 4937 | memset (&p, |
4911 | 0, | 4938 | 0, |
4912 | sizeof (p)); | 4939 | sizeof (p)); |
@@ -5070,7 +5097,7 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) | |||
5070 | 5097 | ||
5071 | #ifdef MHD_USE_THREADS | 5098 | #ifdef MHD_USE_THREADS |
5072 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 5099 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
5073 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 5100 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
5074 | #endif /* MHD_USE_THREADS */ | 5101 | #endif /* MHD_USE_THREADS */ |
5075 | 5102 | ||
5076 | num_events = MAX_EVENTS; | 5103 | num_events = MAX_EVENTS; |
@@ -5209,6 +5236,13 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
5209 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 5236 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
5210 | bool need_to_accept; | 5237 | bool need_to_accept; |
5211 | 5238 | ||
5239 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
5240 | (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); | ||
5241 | mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
5242 | (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); | ||
5243 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
5244 | (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); | ||
5245 | |||
5212 | if (-1 == daemon->epoll_fd) | 5246 | if (-1 == daemon->epoll_fd) |
5213 | return MHD_NO; /* we're down! */ | 5247 | return MHD_NO; /* we're down! */ |
5214 | if (daemon->shutdown) | 5248 | if (daemon->shutdown) |
@@ -5569,6 +5603,8 @@ MHD_run_wait (struct MHD_Daemon *daemon, | |||
5569 | (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ) | 5603 | (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ) |
5570 | return MHD_NO; | 5604 | return MHD_NO; |
5571 | 5605 | ||
5606 | mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)); | ||
5607 | |||
5572 | if (0 > millisec) | 5608 | if (0 > millisec) |
5573 | millisec = -1; | 5609 | millisec = -1; |
5574 | #ifdef HAVE_POLL | 5610 | #ifdef HAVE_POLL |
@@ -5611,7 +5647,7 @@ close_connection (struct MHD_Connection *pos) | |||
5611 | 5647 | ||
5612 | #ifdef MHD_USE_THREADS | 5648 | #ifdef MHD_USE_THREADS |
5613 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 5649 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
5614 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 5650 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
5615 | mhd_assert (NULL == daemon->worker_pool); | 5651 | mhd_assert (NULL == daemon->worker_pool); |
5616 | #endif /* MHD_USE_THREADS */ | 5652 | #endif /* MHD_USE_THREADS */ |
5617 | 5653 | ||
@@ -5665,7 +5701,7 @@ MHD_polling_thread (void *cls) | |||
5665 | int err; | 5701 | int err; |
5666 | #endif /* HAVE_PTHREAD_SIGMASK */ | 5702 | #endif /* HAVE_PTHREAD_SIGMASK */ |
5667 | 5703 | ||
5668 | MHD_thread_init_ (&(daemon->tid)); | 5704 | MHD_thread_handle_ID_set_current_thread_ID_ (&(daemon->tid)); |
5669 | #ifdef HAVE_PTHREAD_SIGMASK | 5705 | #ifdef HAVE_PTHREAD_SIGMASK |
5670 | if ((0 == sigemptyset (&s_mask)) && | 5706 | if ((0 == sigemptyset (&s_mask)) && |
5671 | (0 == sigaddset (&s_mask, SIGPIPE))) | 5707 | (0 == sigaddset (&s_mask, SIGPIPE))) |
@@ -7173,6 +7209,9 @@ MHD_start_daemon_va (unsigned int flags, | |||
7173 | daemon->unescape_callback = &unescape_wrapper; | 7209 | daemon->unescape_callback = &unescape_wrapper; |
7174 | daemon->connection_timeout_ms = 0; /* no timeout */ | 7210 | daemon->connection_timeout_ms = 0; /* no timeout */ |
7175 | MHD_itc_set_invalid_ (daemon->itc); | 7211 | MHD_itc_set_invalid_ (daemon->itc); |
7212 | #ifdef MHD_USE_THREADS | ||
7213 | MHD_thread_handle_ID_set_invalid_ (&daemon->tid); | ||
7214 | #endif /* MHD_USE_THREADS */ | ||
7176 | #ifdef SOMAXCONN | 7215 | #ifdef SOMAXCONN |
7177 | daemon->listen_backlog_size = SOMAXCONN; | 7216 | daemon->listen_backlog_size = SOMAXCONN; |
7178 | #else /* !SOMAXCONN */ | 7217 | #else /* !SOMAXCONN */ |
@@ -8175,7 +8214,7 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
8175 | #ifdef MHD_USE_THREADS | 8214 | #ifdef MHD_USE_THREADS |
8176 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 8215 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
8177 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \ | 8216 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \ |
8178 | MHD_thread_ID_is_current_thread_ (daemon->tid) ); | 8217 | MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); |
8179 | mhd_assert (NULL == daemon->worker_pool); | 8218 | mhd_assert (NULL == daemon->worker_pool); |
8180 | #endif /* MHD_USE_THREADS */ | 8219 | #endif /* MHD_USE_THREADS */ |
8181 | mhd_assert (daemon->shutdown); | 8220 | mhd_assert (daemon->shutdown); |
@@ -8288,7 +8327,7 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
8288 | * MHD_resume_connection() during finishing of "upgraded" | 8327 | * MHD_resume_connection() during finishing of "upgraded" |
8289 | * thread. */ | 8328 | * thread. */ |
8290 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 8329 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
8291 | if (! MHD_join_thread_tid_ (&pos->tid)) | 8330 | if (! MHD_thread_handle_ID_join_thread_ (pos->tid)) |
8292 | MHD_PANIC (_ ("Failed to join a thread.\n")); | 8331 | MHD_PANIC (_ ("Failed to join a thread.\n")); |
8293 | pos->thread_joined = true; | 8332 | pos->thread_joined = true; |
8294 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 8333 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
@@ -8320,7 +8359,7 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
8320 | if (! pos->thread_joined) | 8359 | if (! pos->thread_joined) |
8321 | { | 8360 | { |
8322 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 8361 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
8323 | if (! MHD_join_thread_tid_ (&pos->tid)) | 8362 | if (! MHD_thread_handle_ID_join_thread_ (pos->tid)) |
8324 | MHD_PANIC (_ ("Failed to join a thread.\n")); | 8363 | MHD_PANIC (_ ("Failed to join a thread.\n")); |
8325 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 8364 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
8326 | pos->thread_joined = true; | 8365 | pos->thread_joined = true; |
@@ -8380,6 +8419,14 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
8380 | return; | 8419 | return; |
8381 | if ( (daemon->shutdown) && (NULL == daemon->master) ) | 8420 | if ( (daemon->shutdown) && (NULL == daemon->master) ) |
8382 | MHD_PANIC (_ ("MHD_stop_daemon() was called twice.")); | 8421 | MHD_PANIC (_ ("MHD_stop_daemon() was called twice.")); |
8422 | |||
8423 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
8424 | (NULL != daemon->worker_pool) || \ | ||
8425 | (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); | ||
8426 | mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) && | ||
8427 | (NULL == daemon->worker_pool)) || \ | ||
8428 | (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); | ||
8429 | |||
8383 | /* Slave daemons must be stopped by master daemon. */ | 8430 | /* Slave daemons must be stopped by master daemon. */ |
8384 | mhd_assert ( (NULL == daemon->master) || (daemon->shutdown) ); | 8431 | mhd_assert ( (NULL == daemon->master) || (daemon->shutdown) ); |
8385 | 8432 | ||
@@ -8458,7 +8505,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
8458 | mhd_assert (false); /* Should never happen */ | 8505 | mhd_assert (false); /* Should never happen */ |
8459 | } | 8506 | } |
8460 | 8507 | ||
8461 | if (! MHD_join_thread_tid_ (&daemon->tid)) | 8508 | if (! MHD_thread_handle_ID_join_thread_ (daemon->tid)) |
8462 | { | 8509 | { |
8463 | MHD_PANIC (_ ("Failed to join a thread.\n")); | 8510 | MHD_PANIC (_ ("Failed to join a thread.\n")); |
8464 | } | 8511 | } |
@@ -8556,6 +8603,14 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon, | |||
8556 | { | 8603 | { |
8557 | if (NULL == daemon) | 8604 | if (NULL == daemon) |
8558 | return NULL; | 8605 | return NULL; |
8606 | |||
8607 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | ||
8608 | (NULL != daemon->worker_pool) || \ | ||
8609 | (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); | ||
8610 | mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) && | ||
8611 | (NULL == daemon->worker_pool)) || \ | ||
8612 | (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); | ||
8613 | |||
8559 | switch (info_type) | 8614 | switch (info_type) |
8560 | { | 8615 | { |
8561 | case MHD_DAEMON_INFO_KEY_SIZE: | 8616 | 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 @@ | |||
38 | #endif /* HAVE_PTHREAD_NP_H */ | 38 | #endif /* HAVE_PTHREAD_NP_H */ |
39 | #endif /* MHD_USE_THREAD_NAME_ */ | 39 | #endif /* MHD_USE_THREAD_NAME_ */ |
40 | #include <errno.h> | 40 | #include <errno.h> |
41 | #include "mhd_assert.h" | ||
41 | 42 | ||
42 | 43 | ||
43 | #ifndef MHD_USE_THREAD_NAME_ | 44 | #ifndef MHD_USE_THREAD_NAME_ |
@@ -66,7 +67,7 @@ | |||
66 | * @return non-zero on success, zero otherwise | 67 | * @return non-zero on success, zero otherwise |
67 | */ | 68 | */ |
68 | static int | 69 | static int |
69 | MHD_set_thread_name_ (const MHD_thread_ID_ thread_id, | 70 | MHD_set_thread_name_ (const MHD_thread_ID_native_ thread_id, |
70 | const char *thread_name) | 71 | const char *thread_name) |
71 | { | 72 | { |
72 | if (NULL == thread_name) | 73 | if (NULL == thread_name) |
@@ -122,7 +123,7 @@ MHD_set_thread_name_ (const MHD_thread_ID_ thread_id, | |||
122 | * @return non-zero on success, zero otherwise | 123 | * @return non-zero on success, zero otherwise |
123 | */ | 124 | */ |
124 | static int | 125 | static int |
125 | MHD_set_thread_name_ (const MHD_thread_ID_ thread_id, | 126 | MHD_set_thread_name_ (const MHD_thread_ID_native_ thread_id, |
126 | const char *thread_name) | 127 | const char *thread_name) |
127 | { | 128 | { |
128 | static const DWORD VC_SETNAME_EXC = 0x406D1388; | 129 | static const DWORD VC_SETNAME_EXC = 0x406D1388; |
@@ -164,7 +165,7 @@ MHD_set_thread_name_ (const MHD_thread_ID_ thread_id, | |||
164 | * @return non-zero on success, zero otherwise | 165 | * @return non-zero on success, zero otherwise |
165 | */ | 166 | */ |
166 | #define MHD_set_cur_thread_name_(n) \ | 167 | #define MHD_set_cur_thread_name_(n) \ |
167 | MHD_set_thread_name_ ((MHD_thread_ID_) -1,(n)) | 168 | MHD_set_thread_name_ ((MHD_thread_ID_native_) -1,(n)) |
168 | #endif /* _MSC_FULL_VER */ | 169 | #endif /* _MSC_FULL_VER */ |
169 | #endif /* MHD_USE_W32_THREADS */ | 170 | #endif /* MHD_USE_W32_THREADS */ |
170 | 171 | ||
@@ -176,20 +177,29 @@ MHD_set_thread_name_ (const MHD_thread_ID_ thread_id, | |||
176 | * | 177 | * |
177 | * If thread is created, thread handle must be freed by MHD_join_thread_(). | 178 | * If thread is created, thread handle must be freed by MHD_join_thread_(). |
178 | * | 179 | * |
179 | * @param thread handle to initialize | 180 | * @param handle_id handle to initialise |
180 | * @param stack_size size of stack for new thread, 0 for default | 181 | * @param stack_size size of stack for new thread, 0 for default |
181 | * @param start_routine main function of thread | 182 | * @param start_routine main function of thread |
182 | * @param arg argument for start_routine | 183 | * @param arg argument for start_routine |
183 | * @return non-zero on success; zero otherwise (with errno set) | 184 | * @return non-zero on success; zero otherwise (with errno set) |
184 | */ | 185 | */ |
185 | int | 186 | int |
186 | MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | 187 | MHD_create_thread_ (MHD_thread_handle_ID_ *handle_id, |
187 | size_t stack_size, | 188 | size_t stack_size, |
188 | MHD_THREAD_START_ROUTINE_ start_routine, | 189 | MHD_THREAD_START_ROUTINE_ start_routine, |
189 | void *arg) | 190 | void *arg) |
190 | { | 191 | { |
191 | #if defined(MHD_USE_POSIX_THREADS) | 192 | #if defined(MHD_USE_POSIX_THREADS) |
192 | int res; | 193 | int res; |
194 | #if defined(MHD_thread_handle_ID_get_native_handle_ptr_) | ||
195 | pthread_t *const new_tid_ptr = | ||
196 | MHD_thread_handle_ID_get_native_handle_ptr_ (handle_id); | ||
197 | #else /* ! MHD_thread_handle_ID_get_native_handle_ptr_ */ | ||
198 | pthread_t new_tid; | ||
199 | pthread_t *const new_tid_ptr = &new_tid; | ||
200 | #endif /* ! MHD_thread_handle_ID_get_native_handle_ptr_ */ | ||
201 | |||
202 | mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (*handle_id)); | ||
193 | 203 | ||
194 | if (0 != stack_size) | 204 | if (0 != stack_size) |
195 | { | 205 | { |
@@ -200,7 +210,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | |||
200 | res = pthread_attr_setstacksize (&attr, | 210 | res = pthread_attr_setstacksize (&attr, |
201 | stack_size); | 211 | stack_size); |
202 | if (0 == res) | 212 | if (0 == res) |
203 | res = pthread_create (&(thread->handle), | 213 | res = pthread_create (new_tid_ptr, |
204 | &attr, | 214 | &attr, |
205 | start_routine, | 215 | start_routine, |
206 | arg); | 216 | arg); |
@@ -208,18 +218,28 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | |||
208 | } | 218 | } |
209 | } | 219 | } |
210 | else | 220 | else |
211 | res = pthread_create (&(thread->handle), | 221 | res = pthread_create (new_tid_ptr, |
212 | NULL, | 222 | NULL, |
213 | start_routine, | 223 | start_routine, |
214 | arg); | 224 | arg); |
215 | 225 | ||
216 | if (0 != res) | 226 | if (0 != res) |
227 | { | ||
217 | errno = res; | 228 | errno = res; |
229 | MHD_thread_handle_ID_set_invalid_ (handle_id); | ||
230 | } | ||
231 | #if ! defined(MHD_thread_handle_ID_get_native_handle_ptr_) | ||
232 | else | ||
233 | MHD_thread_handle_ID_set_native_handle_ (handle_id, new_tid); | ||
234 | #endif /* ! MHD_thread_handle_ID_set_current_thread_ID_ */ | ||
218 | 235 | ||
219 | return ! res; | 236 | return ! res; |
220 | #elif defined(MHD_USE_W32_THREADS) | 237 | #elif defined(MHD_USE_W32_THREADS) |
221 | uintptr_t thr_handle; | 238 | uintptr_t thr_handle; |
222 | #if SIZEOF_SIZE_T != SIZEOF_UNSIGNED_INT | 239 | #if SIZEOF_SIZE_T != SIZEOF_UNSIGNED_INT |
240 | |||
241 | mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (*handle_id)); | ||
242 | |||
223 | if (stack_size > UINT_MAX) | 243 | if (stack_size > UINT_MAX) |
224 | { | 244 | { |
225 | errno = EINVAL; | 245 | errno = EINVAL; |
@@ -232,11 +252,13 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | |||
232 | arg, | 252 | arg, |
233 | 0, | 253 | 0, |
234 | NULL); | 254 | NULL); |
235 | thread->handle = (MHD_thread_handle_) thr_handle; | 255 | if ((MHD_thread_handle_native_) 0 == (MHD_thread_handle_native_) thr_handle) |
236 | |||
237 | if ((MHD_thread_handle_) 0 == thread->handle) | ||
238 | return 0; | 256 | return 0; |
239 | 257 | ||
258 | MHD_thread_handle_ID_set_native_handle_ (handle_id, \ | ||
259 | (MHD_thread_handle_native_) \ | ||
260 | thr_handle); | ||
261 | |||
240 | return ! 0; | 262 | return ! 0; |
241 | #endif | 263 | #endif |
242 | } | 264 | } |
@@ -291,7 +313,7 @@ named_thread_starter (void *data) | |||
291 | /** | 313 | /** |
292 | * Create a named thread and set the attributes according to our options. | 314 | * Create a named thread and set the attributes according to our options. |
293 | * | 315 | * |
294 | * @param thread handle to initialize | 316 | * @param handle_id handle to initialise |
295 | * @param thread_name name for new thread | 317 | * @param thread_name name for new thread |
296 | * @param stack_size size of stack for new thread, 0 for default | 318 | * @param stack_size size of stack for new thread, 0 for default |
297 | * @param start_routine main function of thread | 319 | * @param start_routine main function of thread |
@@ -299,7 +321,7 @@ named_thread_starter (void *data) | |||
299 | * @return non-zero on success; zero otherwise (with errno set) | 321 | * @return non-zero on success; zero otherwise (with errno set) |
300 | */ | 322 | */ |
301 | int | 323 | int |
302 | MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, | 324 | MHD_create_named_thread_ (MHD_thread_handle_ID_ *handle_id, |
303 | const char *thread_name, | 325 | const char *thread_name, |
304 | size_t stack_size, | 326 | size_t stack_size, |
305 | MHD_THREAD_START_ROUTINE_ start_routine, | 327 | MHD_THREAD_START_ROUTINE_ start_routine, |
@@ -308,15 +330,22 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, | |||
308 | #if defined(MHD_USE_THREAD_ATTR_SETNAME) | 330 | #if defined(MHD_USE_THREAD_ATTR_SETNAME) |
309 | int res; | 331 | int res; |
310 | pthread_attr_t attr; | 332 | pthread_attr_t attr; |
333 | #if defined(MHD_thread_handle_ID_get_native_handle_ptr_) | ||
334 | pthread_t *const new_tid_ptr = | ||
335 | MHD_thread_handle_ID_get_native_handle_ptr_ (handle_id); | ||
336 | #else /* ! MHD_thread_handle_ID_get_native_handle_ptr_ */ | ||
337 | pthread_t new_tid; | ||
338 | pthread_t *const new_tid_ptr = &new_tid; | ||
339 | #endif /* ! MHD_thread_handle_ID_get_native_handle_ptr_ */ | ||
311 | 340 | ||
312 | res = pthread_attr_init (&attr); | 341 | res = pthread_attr_init (&attr); |
313 | if (0 == res) | 342 | if (0 == res) |
314 | { | 343 | { |
315 | #if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) | 344 | #if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) |
316 | /* NetBSD use 3 arguments: second argument is string in printf-like format, | 345 | /* NetBSD uses 3 arguments: second argument is string in printf-like format, |
317 | * third argument is single argument for printf; | 346 | * third argument is single argument for printf; |
318 | * OSF1 use 3 arguments too, but last one always must be zero (NULL). | 347 | * OSF1 uses 3 arguments too, but last one always must be zero (NULL). |
319 | * MHD doesn't use '%' in thread names, so both form are used in same way. | 348 | * MHD doesn't use '%' in thread names, so both forms are used in same way. |
320 | */ | 349 | */ |
321 | res = pthread_attr_setname_np (&attr, | 350 | res = pthread_attr_setname_np (&attr, |
322 | thread_name, | 351 | thread_name, |
@@ -331,14 +360,21 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, | |||
331 | res = pthread_attr_setstacksize (&attr, | 360 | res = pthread_attr_setstacksize (&attr, |
332 | stack_size); | 361 | stack_size); |
333 | if (0 == res) | 362 | if (0 == res) |
334 | res = pthread_create (&(thread->handle), | 363 | res = pthread_create (new_tid_ptr, |
335 | &attr, | 364 | &attr, |
336 | start_routine, | 365 | start_routine, |
337 | arg); | 366 | arg); |
338 | pthread_attr_destroy (&attr); | 367 | pthread_attr_destroy (&attr); |
339 | } | 368 | } |
340 | if (0 != res) | 369 | if (0 != res) |
370 | { | ||
341 | errno = res; | 371 | errno = res; |
372 | MHD_thread_handle_ID_set_invalid_ (handle_id); | ||
373 | } | ||
374 | #if ! defined(MHD_thread_handle_ID_get_native_handle_ptr_) | ||
375 | else | ||
376 | MHD_thread_handle_ID_set_native_handle_ (handle_id, new_tid); | ||
377 | #endif /* ! MHD_thread_handle_ID_set_current_thread_ID_ */ | ||
342 | 378 | ||
343 | return ! res; | 379 | return ! res; |
344 | #else /* ! MHD_USE_THREAD_ATTR_SETNAME */ | 380 | #else /* ! MHD_USE_THREAD_ATTR_SETNAME */ |
@@ -361,12 +397,16 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, | |||
361 | /* Set thread name in thread itself to avoid problems with | 397 | /* Set thread name in thread itself to avoid problems with |
362 | * threads which terminated before name is set in other thread. | 398 | * threads which terminated before name is set in other thread. |
363 | */ | 399 | */ |
364 | if (! MHD_create_thread_ (thread, | 400 | if (! MHD_create_thread_ (handle_id, |
365 | stack_size, | 401 | stack_size, |
366 | &named_thread_starter, | 402 | &named_thread_starter, |
367 | (void *) param)) | 403 | (void *) param)) |
368 | { | 404 | { |
405 | int err_num; | ||
406 | |||
407 | err_num = errno; | ||
369 | free (param); | 408 | free (param); |
409 | errno = err_num; | ||
370 | return 0; | 410 | return 0; |
371 | } | 411 | } |
372 | 412 | ||
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 @@ | |||
64 | # error No threading API is available. | 64 | # error No threading API is available. |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | #ifdef HAVE_STDBOOL_H | ||
68 | # include <stdbool.h> | ||
69 | #endif /* HAVE_STDBOOL_H */ | ||
70 | |||
71 | #if defined(MHD_USE_POSIX_THREADS) && defined(MHD_USE_W32_THREADS) | ||
72 | # error Both MHD_USE_POSIX_THREADS and MHD_USE_W32_THREADS are defined | ||
73 | #endif /* MHD_USE_POSIX_THREADS && MHD_USE_W32_THREADS */ | ||
74 | |||
67 | #ifndef MHD_NO_THREAD_NAMES | 75 | #ifndef MHD_NO_THREAD_NAMES |
68 | # if defined(MHD_USE_POSIX_THREADS) | 76 | # if defined(MHD_USE_POSIX_THREADS) |
69 | # if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \ | 77 | # if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \ |
@@ -82,26 +90,305 @@ | |||
82 | # endif | 90 | # endif |
83 | #endif | 91 | #endif |
84 | 92 | ||
93 | /* ** Thread handle - used to control the thread ** */ | ||
94 | |||
85 | #if defined(MHD_USE_POSIX_THREADS) | 95 | #if defined(MHD_USE_POSIX_THREADS) |
86 | typedef pthread_t MHD_thread_handle_; | 96 | /** |
97 | * Wait until specified thread is ended and free thread handle on success. | ||
98 | * @param thread handle to watch | ||
99 | * @return nonzero on success, zero otherwise | ||
100 | */ | ||
101 | # define MHD_join_thread_(native_handle) \ | ||
102 | (! pthread_join ((native_handle), NULL)) | ||
87 | #elif defined(MHD_USE_W32_THREADS) | 103 | #elif defined(MHD_USE_W32_THREADS) |
88 | typedef HANDLE MHD_thread_handle_; | 104 | /** |
105 | * Wait until specified thread is ended and free thread handle on success. | ||
106 | * @param thread handle to watch | ||
107 | * @return nonzero on success, zero otherwise | ||
108 | */ | ||
109 | # define MHD_join_thread_(native_handle) \ | ||
110 | ( (WAIT_OBJECT_0 == WaitForSingleObject ( (native_handle), INFINITE)) ? \ | ||
111 | (CloseHandle ( (native_handle)), ! 0) : 0 ) | ||
89 | #endif | 112 | #endif |
90 | 113 | ||
91 | #if defined(MHD_USE_POSIX_THREADS) | 114 | #if defined(MHD_USE_POSIX_THREADS) |
92 | # define MHD_THRD_RTRN_TYPE_ void* | 115 | /** |
93 | # define MHD_THRD_CALL_SPEC_ | 116 | * The native type to control the thread from other threads |
117 | */ | ||
118 | typedef pthread_t MHD_thread_handle_native_; | ||
94 | #elif defined(MHD_USE_W32_THREADS) | 119 | #elif defined(MHD_USE_W32_THREADS) |
95 | # define MHD_THRD_RTRN_TYPE_ unsigned | 120 | /** |
96 | # define MHD_THRD_CALL_SPEC_ __stdcall | 121 | * The native type to control the thread from other threads |
122 | */ | ||
123 | typedef HANDLE MHD_thread_handle_native_; | ||
97 | #endif | 124 | #endif |
98 | 125 | ||
99 | #if defined(MHD_USE_POSIX_THREADS) | 126 | #if defined(MHD_USE_POSIX_THREADS) |
100 | typedef pthread_t MHD_thread_ID_; | 127 | # if defined(__gnu_linux__) || \ |
128 | (defined(__linux__) && defined(__GLIBC__)) | ||
129 | /* The next part of code is disabled because it relies on undocumented | ||
130 | behaviour. | ||
131 | It could be enabled for neglectable performance and size improvements. */ | ||
132 | # if 0 /* Disabled code */ | ||
133 | /** | ||
134 | * The native invalid value for native thread handle | ||
135 | */ | ||
136 | # define MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ \ | ||
137 | ((MHD_thread_handle_native_) 0) | ||
138 | # endif /* Disabled code */ | ||
139 | # endif /* __gnu_linux__ || (__linux__ && __GLIBC__) */ | ||
101 | #elif defined(MHD_USE_W32_THREADS) | 140 | #elif defined(MHD_USE_W32_THREADS) |
102 | typedef DWORD MHD_thread_ID_; | 141 | /** |
142 | * The native invalid value for native thread handle | ||
143 | */ | ||
144 | # define MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ \ | ||
145 | ((MHD_thread_handle_native_) NULL) | ||
146 | #endif /* MHD_USE_W32_THREADS */ | ||
147 | |||
148 | #if ! defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) | ||
149 | /** | ||
150 | * Structure with thread handle and validity flag | ||
151 | */ | ||
152 | struct MHD_thread_handle_struct_ | ||
153 | { | ||
154 | bool valid; /**< true if native handle is set */ | ||
155 | MHD_thread_handle_native_ native; /**< the native thread handle */ | ||
156 | }; | ||
157 | /** | ||
158 | * Type with thread handle that can be set to invalid value | ||
159 | */ | ||
160 | typedef struct MHD_thread_handle_struct_ MHD_thread_handle_; | ||
161 | |||
162 | /** | ||
163 | * Set variable pointed by @a handle_ptr to invalid (unset) value | ||
164 | */ | ||
165 | # define MHD_thread_handle_set_invalid_(handle_ptr) \ | ||
166 | ((handle_ptr)->valid = false) | ||
167 | /** | ||
168 | * Set native handle in variable pointed by @a handle_ptr | ||
169 | * to @a native_val value | ||
170 | */ | ||
171 | # define MHD_thread_handle_set_native_(handle_ptr,native_val) \ | ||
172 | ((handle_ptr)->valid = true, (handle_ptr)->native = native_val) | ||
173 | /** | ||
174 | * Check whether native handle value is set in @a handle_var variable | ||
175 | */ | ||
176 | # define MHD_thread_handle_is_valid_(handle_var) \ | ||
177 | ((handle_var).valid) | ||
178 | /** | ||
179 | * Get native handle value from @a handle_var variable | ||
180 | */ | ||
181 | # define MHD_thread_handle_get_native_(handle_var) \ | ||
182 | ((handle_var).native) | ||
183 | #else /* MHD_THREAD_HANDLE_NATIVE_INVALID_ */ | ||
184 | /** | ||
185 | * Type with thread handle that can be set to invalid value | ||
186 | */ | ||
187 | typedef MHD_thread_handle_native_ MHD_thread_handle_; | ||
188 | |||
189 | /** | ||
190 | * Set variable pointed by @a handle_ptr to invalid (unset) value | ||
191 | */ | ||
192 | # define MHD_thread_handle_set_invalid_(handle_ptr) \ | ||
193 | ((*(handle_ptr)) = MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) | ||
194 | /** | ||
195 | * Set native handle in the variable pointed by @a handle_ptr | ||
196 | * to @a native_val value | ||
197 | */ | ||
198 | # define MHD_thread_handle_set_native_(handle_ptr,native_val) \ | ||
199 | ((*(handle_ptr)) = native_val) | ||
200 | /** | ||
201 | * Check whether native handle value is set in @a handle_var variable | ||
202 | */ | ||
203 | # define MHD_thread_handle_is_valid_(handle_var) \ | ||
204 | (MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ != handle_var) | ||
205 | /** | ||
206 | * Get native handle value from @a handle_var variable | ||
207 | */ | ||
208 | # define MHD_thread_handle_get_native_(handle_var) \ | ||
209 | (handle_var) | ||
210 | /** | ||
211 | * Get pointer to native handle stored the variable pointed by @a handle_ptr | ||
212 | * @note This macro could not available if direct manipulation of | ||
213 | * the native handle is not possible | ||
214 | */ | ||
215 | # define MHD_thread_handle_get_native_ptr_(handle_ptr) \ | ||
216 | (handle_ptr) | ||
217 | #endif /* MHD_THREAD_HANDLE_NATIVE_INVALID_ */ | ||
218 | |||
219 | |||
220 | /* ** Thread ID - used to check threads match ** */ | ||
221 | |||
222 | #if defined(MHD_USE_POSIX_THREADS) | ||
223 | /** | ||
224 | * The native type used to check whether current thread matches expected thread | ||
225 | */ | ||
226 | typedef pthread_t MHD_thread_ID_native_; | ||
227 | |||
228 | /** | ||
229 | * Function to get the current thread native ID. | ||
230 | */ | ||
231 | # define MHD_thread_ID_native_current_ pthread_self | ||
232 | |||
233 | /** | ||
234 | * Check whether two native thread IDs are equal. | ||
235 | * @return non-zero if equal, zero if not equal | ||
236 | */ | ||
237 | # define MHD_thread_ID_native_equal_(id1,id2) \ | ||
238 | (pthread_equal(id1,id2)) | ||
239 | #elif defined(MHD_USE_W32_THREADS) | ||
240 | /** | ||
241 | * The native type used to check whether current thread matches expected thread | ||
242 | */ | ||
243 | typedef DWORD MHD_thread_ID_native_; | ||
244 | |||
245 | /** | ||
246 | * Function to get the current thread native ID. | ||
247 | */ | ||
248 | # define MHD_thread_ID_native_current_ GetCurrentThreadId | ||
249 | |||
250 | /** | ||
251 | * Check whether two native thread IDs are equal. | ||
252 | * @return non-zero if equal, zero if not equal | ||
253 | */ | ||
254 | # define MHD_thread_ID_native_equal_(id1,id2) \ | ||
255 | ((id1) == (id2)) | ||
103 | #endif | 256 | #endif |
104 | 257 | ||
258 | /** | ||
259 | * Check whether specified thread ID matches current thread. | ||
260 | * @param id the thread ID to match | ||
261 | * @return nonzero on match, zero otherwise | ||
262 | */ | ||
263 | #define MHD_thread_ID_native_is_current_thread_(id) \ | ||
264 | MHD_thread_ID_native_equal_(id, MHD_thread_ID_native_current_()) | ||
265 | |||
266 | |||
267 | #if defined(MHD_USE_POSIX_THREADS) | ||
268 | # if defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) | ||
269 | /** | ||
270 | * The native invalid value for native thread ID | ||
271 | */ | ||
272 | # define MHD_THREAD_ID_NATIVE_VALUE_INVALID_ \ | ||
273 | MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ | ||
274 | # endif /* MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ */ | ||
275 | #elif defined(MHD_USE_W32_THREADS) | ||
276 | /** | ||
277 | * The native invalid value for native thread ID | ||
278 | */ | ||
279 | # define MHD_THREAD_ID_NATIVE_VALUE_INVALID_ \ | ||
280 | ((MHD_thread_ID_native_) 0) | ||
281 | #endif /* MHD_USE_W32_THREADS */ | ||
282 | |||
283 | #if ! defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_) | ||
284 | /** | ||
285 | * Structure with thread id and validity flag | ||
286 | */ | ||
287 | struct MHD_thread_ID_struct_ | ||
288 | { | ||
289 | bool valid; /**< true if native ID is set */ | ||
290 | MHD_thread_ID_native_ native; /**< the native thread ID */ | ||
291 | }; | ||
292 | /** | ||
293 | * Type with thread ID that can be set to invalid value | ||
294 | */ | ||
295 | typedef struct MHD_thread_ID_struct_ MHD_thread_ID_; | ||
296 | |||
297 | /** | ||
298 | * Set variable pointed by @a ID_ptr to invalid (unset) value | ||
299 | */ | ||
300 | # define MHD_thread_ID_set_invalid_(ID_ptr) \ | ||
301 | ((ID_ptr)->valid = false) | ||
302 | /** | ||
303 | * Set native ID in variable pointed by @a ID_ptr | ||
304 | * to @a native_val value | ||
305 | */ | ||
306 | # define MHD_thread_ID_set_native_(ID_ptr,native_val) \ | ||
307 | ((ID_ptr)->valid = true, (ID_ptr)->native = native_val) | ||
308 | /** | ||
309 | * Check whether native ID value is set in @a ID_var variable | ||
310 | */ | ||
311 | # define MHD_thread_ID_is_valid_(ID_var) \ | ||
312 | ((ID_var).valid) | ||
313 | /** | ||
314 | * Get native ID value from @a ID_var variable | ||
315 | */ | ||
316 | # define MHD_thread_ID_get_native_(ID_var) \ | ||
317 | ((ID_var).native) | ||
318 | /** | ||
319 | * Check whether @a ID_var variable is equal current thread | ||
320 | */ | ||
321 | # define MHD_thread_ID_is_current_thread_(ID_var) \ | ||
322 | (MHD_thread_ID_is_valid_(ID_var) && \ | ||
323 | MHD_thread_ID_native_is_current_thread_((ID_var).native)) | ||
324 | #else /* MHD_THREAD_ID_NATIVE_INVALID_ */ | ||
325 | /** | ||
326 | * Type with thread ID that can be set to invalid value | ||
327 | */ | ||
328 | typedef MHD_thread_ID_native_ MHD_thread_ID_; | ||
329 | |||
330 | /** | ||
331 | * Set variable pointed by @a ID_ptr to invalid (unset) value | ||
332 | */ | ||
333 | # define MHD_thread_ID_set_invalid_(ID_ptr) \ | ||
334 | ((*(ID_ptr)) = MHD_THREAD_ID_NATIVE_VALUE_INVALID_) | ||
335 | /** | ||
336 | * Set native ID in variable pointed by @a ID_ptr | ||
337 | * to @a native_val value | ||
338 | */ | ||
339 | # define MHD_thread_ID_set_native_(ID_ptr,native_val) \ | ||
340 | ((*(ID_ptr)) = native_val) | ||
341 | /** | ||
342 | * Check whether native ID value is set in @a ID_var variable | ||
343 | */ | ||
344 | # define MHD_thread_ID_is_valid_(ID_var) \ | ||
345 | (MHD_THREAD_ID_NATIVE_VALUE_INVALID_ != ID_var) | ||
346 | /** | ||
347 | * Get native ID value from @a ID_var variable | ||
348 | */ | ||
349 | # define MHD_thread_ID_get_native_(ID_var) \ | ||
350 | (ID_var) | ||
351 | /** | ||
352 | * Check whether @a ID_var variable is equal current thread | ||
353 | */ | ||
354 | # define MHD_thread_ID_is_current_thread_(ID_var) \ | ||
355 | MHD_thread_ID_native_is_current_thread_(ID_var) | ||
356 | #endif /* MHD_THREAD_ID_NATIVE_INVALID_ */ | ||
357 | |||
358 | /** | ||
359 | * Set current thread ID in variable pointed by @a ID_ptr | ||
360 | */ | ||
361 | # define MHD_thread_ID_set_current_thread_(ID_ptr) \ | ||
362 | MHD_thread_ID_set_native_(ID_ptr,MHD_thread_ID_native_current_()) | ||
363 | |||
364 | |||
365 | #if defined(MHD_USE_POSIX_THREADS) | ||
366 | # if defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) && \ | ||
367 | ! defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_) | ||
368 | # error \ | ||
369 | MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is defined, but MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is not defined | ||
370 | # elif ! defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) && \ | ||
371 | defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_) | ||
372 | # error \ | ||
373 | MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is not defined, but MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is defined | ||
374 | # endif | ||
375 | #endif /* MHD_USE_POSIX_THREADS */ | ||
376 | |||
377 | /* When staring a new thread, the kernel (and thread implementation) may | ||
378 | * pause the calling (initial) thread and start the new thread. | ||
379 | * If thread identifier is assigned to variable in the initial thread then | ||
380 | * the value of the identifier variable will be undefined in the new thread | ||
381 | * until the initial thread continue processing. | ||
382 | * However, it is also possible that the new thread created, but not executed | ||
383 | * for some time while the initial thread continue execution. In this case any | ||
384 | * variable assigned in the new thread will be undefined for some time until | ||
385 | * they really processed by the new thread. | ||
386 | * To avoid data races, a special structure MHD_thread_handle_ID_ is used. | ||
387 | * The "handle" is assigned by calling (initial) thread and should be always | ||
388 | * defined when checked in the initial thread. | ||
389 | * The "ID" is assigned by the new thread and should be always defined when | ||
390 | * checked inside the new thread. | ||
391 | */ | ||
105 | /* Depending on implementation, pthread_create() MAY set thread ID into | 392 | /* Depending on implementation, pthread_create() MAY set thread ID into |
106 | * provided pointer and after it start thread OR start thread and after | 393 | * provided pointer and after it start thread OR start thread and after |
107 | * it set thread ID. In the latter case, to avoid data races, additional | 394 | * it set thread ID. In the latter case, to avoid data races, additional |
@@ -109,95 +396,122 @@ typedef DWORD MHD_thread_ID_; | |||
109 | * is known for setting thread ID BEFORE starting thread macro | 396 | * is known for setting thread ID BEFORE starting thread macro |
110 | * MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD could be defined | 397 | * MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD could be defined |
111 | * to save some resources. */ | 398 | * to save some resources. */ |
399 | /* #define MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD 1 */ | ||
400 | |||
112 | /* * handle - must be valid when other thread knows that particular thread | 401 | /* * handle - must be valid when other thread knows that particular thread |
113 | is started. | 402 | is started. |
114 | * ID - must be valid when code is executed inside thread */ | 403 | * ID - must be valid when code is executed inside thread */ |
115 | #if defined(MHD_USE_POSIX_THREADS) | 404 | #if defined(MHD_USE_POSIX_THREADS) && \ |
116 | # ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD | 405 | defined(MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD) && \ |
406 | defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) && \ | ||
407 | defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_) && \ | ||
408 | defined(MHD_thread_handle_get_native_ptr_) | ||
117 | union _MHD_thread_handle_ID_ | 409 | union _MHD_thread_handle_ID_ |
118 | { | 410 | { |
119 | MHD_thread_handle_ handle; /**< To be used in other threads */ | 411 | MHD_thread_handle_ handle; /**< To be used in other threads */ |
120 | MHD_thread_ID_ ID; /**< To be used in thread itself */ | 412 | MHD_thread_ID_ ID; /**< To be used in the thread itself */ |
121 | }; | 413 | }; |
122 | typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_; | 414 | typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_; |
123 | # else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ | 415 | # define MHD_THREAD_HANDLE_ID_IS_UNION 1 |
124 | struct _MHD_thread_handle_ID_ | 416 | #else /* !MHD_USE_POSIX_THREADS |
125 | { | 417 | || !MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD |
126 | MHD_thread_handle_ handle; /**< To be used in other threads */ | 418 | || !MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ |
127 | MHD_thread_ID_ ID; /**< To be used in thread itself */ | 419 | || !MHD_THREAD_ID_NATIVE_VALUE_INVALID_ |
128 | }; | 420 | || !MHD_thread_handle_get_native_ptr_ */ |
129 | typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_; | ||
130 | # endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ | ||
131 | #elif defined(MHD_USE_W32_THREADS) | ||
132 | struct _MHD_thread_handle_ID_ | 421 | struct _MHD_thread_handle_ID_ |
133 | { | 422 | { |
134 | MHD_thread_handle_ handle; /**< To be used in other threads */ | 423 | MHD_thread_handle_ handle; /**< To be used in other threads */ |
135 | MHD_thread_ID_ ID; /**< To be used in thread itself */ | 424 | MHD_thread_ID_ ID; /**< To be used in the thread itself */ |
136 | }; | 425 | }; |
137 | typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_; | 426 | typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_; |
138 | #endif | 427 | #endif /* !MHD_USE_POSIX_THREADS |
428 | || !MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD | ||
429 | || !MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ | ||
430 | || !MHD_THREAD_ID_NATIVE_VALUE_INVALID_ | ||
431 | || !MHD_thread_handle_get_native_ptr_ */ | ||
139 | 432 | ||
140 | #if defined(MHD_USE_POSIX_THREADS) | ||
141 | /** | 433 | /** |
142 | * Wait until specified thread is ended and free thread handle on success. | 434 | * Set MHD_thread_handle_ID_ to invalid value |
143 | * @param thread handle to watch | ||
144 | * @return nonzero on success, zero otherwise | ||
145 | */ | 435 | */ |
146 | #define MHD_join_thread_(thread) (! pthread_join ((thread), NULL)) | 436 | #define MHD_thread_handle_ID_set_invalid_(hndl_id_ptr) \ |
147 | #elif defined(MHD_USE_W32_THREADS) | 437 | (MHD_thread_handle_set_invalid_(&((hndl_id_ptr)->handle)), \ |
438 | MHD_thread_ID_set_invalid_(&((hndl_id_ptr)->ID))) | ||
439 | |||
148 | /** | 440 | /** |
149 | * Wait until specified thread is ended and free thread handle on success. | 441 | * Check whether thread handle is valid. |
150 | * @param thread handle to watch | 442 | * To be used in threads other then the thread specified by @a hndl_id. |
151 | * @return nonzero on success, zero otherwise | ||
152 | */ | 443 | */ |
153 | #define MHD_join_thread_(thread) \ | 444 | #define MHD_thread_handle_ID_is_valid_handle_(hndl_id) \ |
154 | ( (WAIT_OBJECT_0 == WaitForSingleObject ( (thread), INFINITE)) ? \ | 445 | MHD_thread_handle_is_valid_((hndl_id).handle) |
155 | (CloseHandle ( (thread)), ! 0) : 0 ) | ||
156 | #endif | ||
157 | 446 | ||
158 | #define MHD_join_thread_tid_(thread_handle_ID_ptr) \ | 447 | /** |
159 | (MHD_join_thread_((thread_handle_ID_ptr)->handle)) | 448 | * Set native handle in variable pointed by @a hndl_id_ptr |
449 | * to @a native_val value | ||
450 | */ | ||
451 | #define MHD_thread_handle_ID_set_native_handle_(hndl_id_ptr,native_val) \ | ||
452 | MHD_thread_handle_set_native_(&((hndl_id_ptr)->handle),native_val) | ||
160 | 453 | ||
161 | #if defined(MHD_USE_POSIX_THREADS) | 454 | #if defined(MHD_thread_handle_get_native_ptr_) |
162 | /** | 455 | /** |
163 | * Check whether provided thread ID matches current thread. | 456 | * Get pointer to native handle stored the variable pointed by @a hndl_id_ptr |
164 | * @param ID thread ID to match | 457 | * @note This macro could not available if direct manipulation of |
165 | * @return nonzero on match, zero otherwise | 458 | * the native handle is not possible |
166 | */ | 459 | */ |
167 | # define MHD_thread_ID_is_current_thread_(tid) \ | 460 | # define MHD_thread_handle_ID_get_native_handle_ptr_(hndl_id_ptr) \ |
168 | (pthread_equal ((tid).ID, pthread_self ())) | 461 | MHD_thread_handle_get_native_ptr_(&((hndl_id_ptr)->handle)) |
169 | #elif defined(MHD_USE_W32_THREADS) | 462 | #endif /* MHD_thread_handle_get_native_ptr_ */ |
463 | |||
170 | /** | 464 | /** |
171 | * Check whether provided thread ID matches current thread. | 465 | * Get native thread handle from MHD_thread_handle_ID_ variable. |
172 | * @param ID thread ID to match | ||
173 | * @return nonzero on match, zero otherwise | ||
174 | */ | 466 | */ |
175 | # define MHD_thread_ID_is_current_thread_(tid) \ | 467 | #define MHD_thread_handle_ID_get_native_handle_(hndl_id) \ |
176 | (GetCurrentThreadId () == (tid).ID) | 468 | MHD_thread_handle_get_native_((hndl_id).handle) |
177 | #endif | ||
178 | 469 | ||
179 | #if defined(MHD_USE_POSIX_THREADS) | ||
180 | # ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD | ||
181 | /** | 470 | /** |
182 | * Initialise thread ID. | 471 | * Check whether thread ID is valid. |
183 | * @param thread_handle_ID_ptr pointer to thread handle-ID | 472 | * To be used in the thread itself. |
473 | */ | ||
474 | #define MHD_thread_handle_ID_is_valid_ID_(hndl_id) \ | ||
475 | MHD_thread_ID_is_valid_((hndl_id).ID) | ||
476 | |||
477 | #if defined(MHD_THREAD_HANDLE_ID_IS_UNION) | ||
478 | # if defined(MHD_USE_W32_THREADS) | ||
479 | # error MHD_thread_handle_ID_ cannot be a union with W32 threads | ||
480 | # endif /* MHD_USE_W32_THREADS */ | ||
481 | /** | ||
482 | * Set current thread ID in the variable pointed by @a hndl_id_ptr | ||
184 | */ | 483 | */ |
185 | #define MHD_thread_init_(thread_handle_ID_ptr) (void) 0 | 484 | # define MHD_thread_handle_ID_set_current_thread_ID_(hndl_id_ptr) (void) 0 |
186 | # else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ | 485 | #else /* ! MHD_THREAD_HANDLE_ID_IS_UNION */ |
187 | /** | 486 | /** |
188 | * Initialise thread ID. | 487 | * Set current thread ID in the variable pointed by @a hndl_id_ptr |
189 | * @param thread_handle_ID_ptr pointer to thread handle-ID | ||
190 | */ | 488 | */ |
191 | #define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \ | 489 | # define MHD_thread_handle_ID_set_current_thread_ID_(hndl_id_ptr) \ |
192 | pthread_self ()) | 490 | MHD_thread_ID_set_current_thread_(&((hndl_id_ptr)->ID)) |
193 | # endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ | 491 | #endif /* ! MHD_THREAD_HANDLE_ID_IS_UNION */ |
194 | #elif defined(MHD_USE_W32_THREADS) | 492 | |
493 | /** | ||
494 | * Check whether provided thread ID matches current thread. | ||
495 | * @param ID thread ID to match | ||
496 | * @return nonzero on match, zero otherwise | ||
497 | */ | ||
498 | #define MHD_thread_handle_ID_is_current_thread_(hndl_id) \ | ||
499 | MHD_thread_ID_is_current_thread_((hndl_id).ID) | ||
500 | |||
195 | /** | 501 | /** |
196 | * Initialise thread ID. | 502 | * Wait until specified thread is ended and free thread handle on success. |
197 | * @param thread_handle_ID_ptr pointer to thread handle-ID | 503 | * @param hndl_id_ handle with ID to watch |
504 | * @return nonzero on success, zero otherwise | ||
198 | */ | 505 | */ |
199 | #define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \ | 506 | #define MHD_thread_handle_ID_join_thread_(hndl_id) \ |
200 | GetCurrentThreadId ()) | 507 | MHD_join_thread_(MHD_thread_handle_ID_get_native_handle_(hndl_id)) |
508 | |||
509 | #if defined(MHD_USE_POSIX_THREADS) | ||
510 | # define MHD_THRD_RTRN_TYPE_ void* | ||
511 | # define MHD_THRD_CALL_SPEC_ | ||
512 | #elif defined(MHD_USE_W32_THREADS) | ||
513 | # define MHD_THRD_RTRN_TYPE_ unsigned | ||
514 | # define MHD_THRD_CALL_SPEC_ __stdcall | ||
201 | #endif | 515 | #endif |
202 | 516 | ||
203 | /** | 517 | /** |
@@ -215,14 +529,14 @@ typedef MHD_THRD_RTRN_TYPE_ | |||
215 | * | 529 | * |
216 | * If thread is created, thread handle must be freed by MHD_join_thread_(). | 530 | * If thread is created, thread handle must be freed by MHD_join_thread_(). |
217 | * | 531 | * |
218 | * @param thread handle to initialize | 532 | * @param handle_id handle to initialise |
219 | * @param stack_size size of stack for new thread, 0 for default | 533 | * @param stack_size size of stack for new thread, 0 for default |
220 | * @param start_routine main function of thread | 534 | * @param start_routine main function of thread |
221 | * @param arg argument for start_routine | 535 | * @param arg argument for start_routine |
222 | * @return non-zero on success; zero otherwise (with errno set) | 536 | * @return non-zero on success; zero otherwise (with errno set) |
223 | */ | 537 | */ |
224 | int | 538 | int |
225 | MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | 539 | MHD_create_thread_ (MHD_thread_handle_ID_ *handle_id, |
226 | size_t stack_size, | 540 | size_t stack_size, |
227 | MHD_THREAD_START_ROUTINE_ start_routine, | 541 | MHD_THREAD_START_ROUTINE_ start_routine, |
228 | void *arg); | 542 | void *arg); |
@@ -233,7 +547,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | |||
233 | /** | 547 | /** |
234 | * Create a named thread and set the attributes according to our options. | 548 | * Create a named thread and set the attributes according to our options. |
235 | * | 549 | * |
236 | * @param thread handle to initialize | 550 | * @param handle_id handle to initialise |
237 | * @param thread_name name for new thread | 551 | * @param thread_name name for new thread |
238 | * @param stack_size size of stack for new thread, 0 for default | 552 | * @param stack_size size of stack for new thread, 0 for default |
239 | * @param start_routine main function of thread | 553 | * @param start_routine main function of thread |
@@ -241,7 +555,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | |||
241 | * @return non-zero on success; zero otherwise | 555 | * @return non-zero on success; zero otherwise |
242 | */ | 556 | */ |
243 | int | 557 | int |
244 | MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, | 558 | MHD_create_named_thread_ (MHD_thread_handle_ID_ *handle_id, |
245 | const char *thread_name, | 559 | const char *thread_name, |
246 | size_t stack_size, | 560 | size_t stack_size, |
247 | MHD_THREAD_START_ROUTINE_ start_routine, | 561 | 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, | |||
1941 | 1941 | ||
1942 | #ifdef MHD_USE_THREADS | 1942 | #ifdef MHD_USE_THREADS |
1943 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 1943 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
1944 | MHD_thread_ID_is_current_thread_ (connection->tid) ); | 1944 | MHD_thread_handle_ID_is_current_thread_ (connection->tid) ); |
1945 | #endif /* MHD_USE_THREADS */ | 1945 | #endif /* MHD_USE_THREADS */ |
1946 | 1946 | ||
1947 | /* "Upgrade" responses accepted only if MHD_ALLOW_UPGRADE is enabled */ | 1947 | /* "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) | |||
322 | */ | 322 | */ |
323 | for (i = 0; i < 5 && result == 0; i++) | 323 | for (i = 0; i < 5 && result == 0; i++) |
324 | { | 324 | { |
325 | MHD_thread_handle_ sel_thrd; | 325 | MHD_thread_handle_native_ sel_thrd; |
326 | /* fprintf(stdout, "Creating, binding and listening socket...\n"); */ | 326 | /* fprintf(stdout, "Creating, binding and listening socket...\n"); */ |
327 | MHD_socket listen_socket = start_socket_listen (AF_INET); | 327 | MHD_socket listen_socket = start_socket_listen (AF_INET); |
328 | if (MHD_INVALID_SOCKET == listen_socket) | 328 | if (MHD_INVALID_SOCKET == listen_socket) |