|
@@ -2692,6 +2692,7 @@ struct mg_context {
|
|
|
unsigned int
|
|
|
cfg_worker_threads; /* The number of configured worker threads. */
|
|
|
pthread_t *worker_threadids; /* The worker thread IDs */
|
|
|
+ unsigned long starter_thread_idx; /* thread index which called mg_start */
|
|
|
|
|
|
/* Connection to thread dispatching */
|
|
|
#if defined(ALTERNATIVE_QUEUE)
|
|
@@ -13467,6 +13468,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
{
|
|
|
struct mg_handler_info *tmp_rh, **lastref;
|
|
|
size_t urilen = strlen(uri);
|
|
|
+ struct mg_workerTLS tls;
|
|
|
|
|
|
if (handler_type == WEBSOCKET_HANDLER) {
|
|
|
DEBUG_ASSERT(handler == NULL);
|
|
@@ -13523,6 +13525,14 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ tls.is_master = -1;
|
|
|
+ tls.thread_idx = phys_ctx->starter_thread_idx;
|
|
|
+#if defined(_WIN32)
|
|
|
+ tls.pthread_cond_helper_mutex = NULL;
|
|
|
+#endif
|
|
|
+
|
|
|
+ pthread_setspecific(sTlsKey, &tls);
|
|
|
+
|
|
|
mg_lock_context(phys_ctx);
|
|
|
|
|
|
/* first try to find an existing handler */
|
|
@@ -13564,6 +13574,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
mg_free(tmp_rh);
|
|
|
}
|
|
|
mg_unlock_context(phys_ctx);
|
|
|
+ pthread_setspecific(sTlsKey, NULL);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
@@ -13574,6 +13585,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
/* no handler to set, this was a remove request to a non-existing
|
|
|
* handler */
|
|
|
mg_unlock_context(phys_ctx);
|
|
|
+ pthread_setspecific(sTlsKey, NULL);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -13586,6 +13598,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
mg_cry_ctx_internal(phys_ctx,
|
|
|
"%s",
|
|
|
"Cannot create new request handler struct, OOM");
|
|
|
+ pthread_setspecific(sTlsKey, NULL);
|
|
|
return;
|
|
|
}
|
|
|
tmp_rh->uri = mg_strdup_ctx(uri, phys_ctx);
|
|
@@ -13595,6 +13608,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
mg_cry_ctx_internal(phys_ctx,
|
|
|
"%s",
|
|
|
"Cannot create new request handler struct, OOM");
|
|
|
+ pthread_setspecific(sTlsKey, NULL);
|
|
|
return;
|
|
|
}
|
|
|
tmp_rh->uri_len = urilen;
|
|
@@ -13604,6 +13618,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
mg_unlock_context(phys_ctx);
|
|
|
mg_free(tmp_rh);
|
|
|
mg_cry_ctx_internal(phys_ctx, "%s", "Cannot init refcount mutex");
|
|
|
+ pthread_setspecific(sTlsKey, NULL);
|
|
|
return;
|
|
|
}
|
|
|
if (0 != pthread_cond_init(&tmp_rh->refcount_cond, NULL)) {
|
|
@@ -13611,6 +13626,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
pthread_mutex_destroy(&tmp_rh->refcount_mutex);
|
|
|
mg_free(tmp_rh);
|
|
|
mg_cry_ctx_internal(phys_ctx, "%s", "Cannot init refcount cond");
|
|
|
+ pthread_setspecific(sTlsKey, NULL);
|
|
|
return;
|
|
|
}
|
|
|
tmp_rh->refcount = 0;
|
|
@@ -13630,6 +13646,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
|
|
|
*lastref = tmp_rh;
|
|
|
mg_unlock_context(phys_ctx);
|
|
|
+ pthread_setspecific(sTlsKey, NULL);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -18915,8 +18932,12 @@ static
|
|
|
ctx->dd.auth_nonce_mask =
|
|
|
(uint64_t)get_random() ^ (uint64_t)(ptrdiff_t)(options);
|
|
|
|
|
|
+ /* Save started thread index to reuse in other external API calls
|
|
|
+ * For the sake of thread synchronization all non-civetweb threads
|
|
|
+ * can be considered as single external thread */
|
|
|
+ ctx->starter_thread_idx = (unsigned)mg_atomic_inc(&thread_idx_max);
|
|
|
tls.is_master = -1; /* Thread calling mg_start */
|
|
|
- tls.thread_idx = (unsigned)mg_atomic_inc(&thread_idx_max);
|
|
|
+ tls.thread_idx = ctx->starter_thread_idx;
|
|
|
#if defined(_WIN32)
|
|
|
tls.pthread_cond_helper_mutex = NULL;
|
|
|
#endif
|