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