|  | @@ -2759,8 +2759,6 @@ struct mg_connection {
 | 
	
		
			
				|  |  |  #if defined(USE_LUA) && defined(USE_WEBSOCKET)
 | 
	
		
			
				|  |  |  	void *lua_websocket_state; /* Lua_State for a websocket connection */
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	int thread_index; /* Thread index within ctx */
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -5489,9 +5487,9 @@ mg_start_thread_with_id(unsigned(__stdcall *f)(void *),
 | 
	
		
			
				|  |  |  	HANDLE threadhandle;
 | 
	
		
			
				|  |  |  	int result = -1;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	uip = _beginthreadex(NULL, 0, (unsigned(__stdcall *)(void *))f, p, 0, NULL);
 | 
	
		
			
				|  |  | +	uip = _beginthreadex(NULL, 0, f, p, 0, NULL);
 | 
	
		
			
				|  |  |  	threadhandle = (HANDLE)uip;
 | 
	
		
			
				|  |  | -	if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) {
 | 
	
		
			
				|  |  | +	if ((uip != 0) && (threadidptr != NULL)) {
 | 
	
		
			
				|  |  |  		*threadidptr = threadhandle;
 | 
	
		
			
				|  |  |  		result = 0;
 | 
	
		
			
				|  |  |  	}
 | 
	
	
		
			
				|  | @@ -17818,17 +17816,11 @@ produce_socket(struct mg_context *ctx, const struct socket *sp)
 | 
	
		
			
				|  |  |  #endif /* ALTERNATIVE_QUEUE */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -struct worker_thread_args {
 | 
	
		
			
				|  |  | -	struct mg_context *ctx;
 | 
	
		
			
				|  |  | -	int index;
 | 
	
		
			
				|  |  | -};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static void *
 | 
	
		
			
				|  |  | -worker_thread_run(struct worker_thread_args *thread_args)
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  | +worker_thread_run(struct mg_connection *conn)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	struct mg_context *ctx = thread_args->ctx;
 | 
	
		
			
				|  |  | -	struct mg_connection *conn;
 | 
	
		
			
				|  |  | +	struct mg_context *ctx = conn->phys_ctx;
 | 
	
		
			
				|  |  | +	int thread_index;
 | 
	
		
			
				|  |  |  	struct mg_workerTLS tls;
 | 
	
		
			
				|  |  |  #if defined(MG_LEGACY_INTERFACE)
 | 
	
		
			
				|  |  |  	uint32_t addr;
 | 
	
	
		
			
				|  | @@ -17851,15 +17843,15 @@ worker_thread_run(struct worker_thread_args *thread_args)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Connection structure has been pre-allocated */
 | 
	
		
			
				|  |  | -	if (((int)thread_args->index < 0)
 | 
	
		
			
				|  |  | -	    || ((unsigned)thread_args->index
 | 
	
		
			
				|  |  | +	thread_index = (int)(conn - ctx->worker_connections);
 | 
	
		
			
				|  |  | +	if ((thread_index < 0)
 | 
	
		
			
				|  |  | +	    || ((unsigned)thread_index
 | 
	
		
			
				|  |  |  	        >= (unsigned)ctx->cfg_worker_threads)) {
 | 
	
		
			
				|  |  |  		mg_cry_internal(fc(ctx),
 | 
	
		
			
				|  |  |  		                "Internal error: Invalid worker index %i",
 | 
	
		
			
				|  |  | -		                (int)thread_args->index);
 | 
	
		
			
				|  |  | -		return NULL;
 | 
	
		
			
				|  |  | +		                thread_index);
 | 
	
		
			
				|  |  | +		return;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	conn = ctx->worker_connections + thread_args->index;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Request buffers are not pre-allocated. They are private to the
 | 
	
		
			
				|  |  |  	 * request and do not contain any state information that might be
 | 
	
	
		
			
				|  | @@ -17868,16 +17860,14 @@ worker_thread_run(struct worker_thread_args *thread_args)
 | 
	
		
			
				|  |  |  	if (conn->buf == NULL) {
 | 
	
		
			
				|  |  |  		mg_cry_internal(fc(ctx),
 | 
	
		
			
				|  |  |  		                "Out of memory: Cannot allocate buffer for worker %i",
 | 
	
		
			
				|  |  | -		                (int)thread_args->index);
 | 
	
		
			
				|  |  | -		return NULL;
 | 
	
		
			
				|  |  | +		                thread_index);
 | 
	
		
			
				|  |  | +		return;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	conn->buf_size = (int)ctx->max_request_size;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	conn->phys_ctx = ctx;
 | 
	
		
			
				|  |  |  	conn->dom_ctx = &(ctx->dd); /* Use default domain and default host */
 | 
	
		
			
				|  |  |  	conn->host = NULL;          /* until we have more information. */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	conn->thread_index = thread_args->index;
 | 
	
		
			
				|  |  |  	conn->request_info.user_data = ctx->user_data;
 | 
	
		
			
				|  |  |  	/* Allocate a mutex for this connection to allow communication both
 | 
	
		
			
				|  |  |  	 * within the request handler and from elsewhere in the application
 | 
	
	
		
			
				|  | @@ -17885,7 +17875,7 @@ worker_thread_run(struct worker_thread_args *thread_args)
 | 
	
		
			
				|  |  |  	if (0 != pthread_mutex_init(&conn->mutex, &pthread_mutex_attr)) {
 | 
	
		
			
				|  |  |  		mg_free(conn->buf);
 | 
	
		
			
				|  |  |  		mg_cry_internal(fc(ctx), "%s", "Cannot create mutex");
 | 
	
		
			
				|  |  | -		return NULL;
 | 
	
		
			
				|  |  | +		return;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #if defined(USE_SERVER_STATS)
 | 
	
	
		
			
				|  | @@ -17895,7 +17885,7 @@ worker_thread_run(struct worker_thread_args *thread_args)
 | 
	
		
			
				|  |  |  	/* Call consume_socket() even when ctx->stop_flag > 0, to let it
 | 
	
		
			
				|  |  |  	 * signal sq_empty condvar to wake up the master waiting in
 | 
	
		
			
				|  |  |  	 * produce_socket() */
 | 
	
		
			
				|  |  | -	while (consume_socket(ctx, &conn->client, conn->thread_index)) {
 | 
	
		
			
				|  |  | +	while (consume_socket(ctx, &conn->client, thread_index)) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		conn->conn_birth_time = time(NULL);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -17986,7 +17976,6 @@ worker_thread_run(struct worker_thread_args *thread_args)
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	DEBUG_TRACE("%s", "exiting");
 | 
	
		
			
				|  |  | -	return NULL;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -17994,18 +17983,13 @@ worker_thread_run(struct worker_thread_args *thread_args)
 | 
	
		
			
				|  |  |  #if defined(_WIN32)
 | 
	
		
			
				|  |  |  static unsigned __stdcall worker_thread(void *thread_func_param)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	struct worker_thread_args *pwta =
 | 
	
		
			
				|  |  | -	    (struct worker_thread_args *)thread_func_param;
 | 
	
		
			
				|  |  | -	worker_thread_run(pwta);
 | 
	
		
			
				|  |  | -	mg_free(thread_func_param);
 | 
	
		
			
				|  |  | +	worker_thread_run((struct mg_connection *)thread_func_param);
 | 
	
		
			
				|  |  |  	return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  #else
 | 
	
		
			
				|  |  |  static void *
 | 
	
		
			
				|  |  |  worker_thread(void *thread_func_param)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	struct worker_thread_args *pwta =
 | 
	
		
			
				|  |  | -	    (struct worker_thread_args *)thread_func_param;
 | 
	
		
			
				|  |  |  	struct sigaction sa;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Ignore SIGPIPE */
 | 
	
	
		
			
				|  | @@ -18013,8 +17997,7 @@ worker_thread(void *thread_func_param)
 | 
	
		
			
				|  |  |  	sa.sa_handler = SIG_IGN;
 | 
	
		
			
				|  |  |  	sigaction(SIGPIPE, &sa, NULL);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	worker_thread_run(pwta);
 | 
	
		
			
				|  |  | -	mg_free(thread_func_param);
 | 
	
		
			
				|  |  | +	worker_thread_run((struct mg_connection *)thread_func_param);
 | 
	
		
			
				|  |  |  	return NULL;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  #endif /* _WIN32 */
 | 
	
	
		
			
				|  | @@ -18106,9 +18089,8 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void
 | 
	
		
			
				|  |  | -master_thread_run(void *thread_func_param)
 | 
	
		
			
				|  |  | +master_thread_run(struct mg_context *ctx)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	struct mg_context *ctx = (struct mg_context *)thread_func_param;
 | 
	
		
			
				|  |  |  	struct mg_workerTLS tls;
 | 
	
		
			
				|  |  |  	struct mg_pollfd *pfd;
 | 
	
		
			
				|  |  |  	unsigned int i;
 | 
	
	
		
			
				|  | @@ -18230,7 +18212,7 @@ master_thread_run(void *thread_func_param)
 | 
	
		
			
				|  |  |  #if defined(_WIN32)
 | 
	
		
			
				|  |  |  static unsigned __stdcall master_thread(void *thread_func_param)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	master_thread_run(thread_func_param);
 | 
	
		
			
				|  |  | +	master_thread_run((struct mg_context *)thread_func_param);
 | 
	
		
			
				|  |  |  	return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  #else
 | 
	
	
		
			
				|  | @@ -18244,7 +18226,7 @@ master_thread(void *thread_func_param)
 | 
	
		
			
				|  |  |  	sa.sa_handler = SIG_IGN;
 | 
	
		
			
				|  |  |  	sigaction(SIGPIPE, &sa, NULL);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	master_thread_run(thread_func_param);
 | 
	
		
			
				|  |  | +	master_thread_run((struct mg_context *)thread_func_param);
 | 
	
		
			
				|  |  |  	return NULL;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  #endif /* _WIN32 */
 | 
	
	
		
			
				|  | @@ -18738,24 +18720,13 @@ mg_start(const struct mg_callbacks *callbacks,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Start worker threads */
 | 
	
		
			
				|  |  |  	for (i = 0; i < ctx->cfg_worker_threads; i++) {
 | 
	
		
			
				|  |  | -		struct worker_thread_args *wta = (struct worker_thread_args *)
 | 
	
		
			
				|  |  | -		    mg_malloc_ctx(sizeof(struct worker_thread_args), ctx);
 | 
	
		
			
				|  |  | -		if (wta) {
 | 
	
		
			
				|  |  | -			wta->ctx = ctx;
 | 
	
		
			
				|  |  | -			wta->index = (int)i;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if ((wta == NULL)
 | 
	
		
			
				|  |  | -		    || (mg_start_thread_with_id(worker_thread,
 | 
	
		
			
				|  |  | -		                                wta,
 | 
	
		
			
				|  |  | -		                                &ctx->worker_threadids[i])
 | 
	
		
			
				|  |  | -		        != 0)) {
 | 
	
		
			
				|  |  | +		/* worker_thread sets up the other fields */
 | 
	
		
			
				|  |  | +		ctx->worker_connections[i].phys_ctx = ctx;
 | 
	
		
			
				|  |  | +		if (mg_start_thread_with_id(worker_thread,
 | 
	
		
			
				|  |  | +		                            &ctx->worker_connections[i],
 | 
	
		
			
				|  |  | +		                            &ctx->worker_threadids[i]) != 0) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			/* thread was not created */
 | 
	
		
			
				|  |  | -			if (wta != NULL) {
 | 
	
		
			
				|  |  | -				mg_free(wta);
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  			if (i > 0) {
 | 
	
		
			
				|  |  |  				mg_cry_internal(fc(ctx),
 | 
	
		
			
				|  |  |  				                "Cannot start worker thread %i: error %ld",
 |