Sfoglia il codice sorgente

Set an unsigned long value in the thread local storage also for the thread starting civetweb.

See discussion in #200.
bel 9 anni fa
parent
commit
9acd4f40eb
1 ha cambiato i file con 21 aggiunte e 3 eliminazioni
  1. 21 3
      src/civetweb.c

+ 21 - 3
src/civetweb.c

@@ -9637,9 +9637,8 @@ static unsigned long ssl_id_callback(void)
 {
 	struct mg_workerTLS *tls =
 	    (struct mg_workerTLS *)pthread_getspecific(sTlsKey);
-	if (tls == NULL) {
-		return 0;
-	}
+	/* Do not check for tls == NULL here. If tls == NULL, something is wrong
+     * and there is no way to fix it here. In particular, do not return 0. */
 	return tls->thread_idx;
 }
 
@@ -11249,6 +11248,8 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 	unsigned int i;
 	void (*exit_callback)(const struct mg_context *ctx) = 0;
 
+	struct mg_workerTLS tls;
+
 #if defined(_WIN32) && !defined(__SYMBIAN32__)
 	WSADATA data;
 	WSAStartup(MAKEWORD(2, 2), &data);
@@ -11280,6 +11281,13 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 		mg_sleep(1);
 	}
 
+	tls.is_master = -1;
+	tls.thread_idx = (unsigned)mg_atomic_inc(&thread_idx_max);
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+	tls.pthread_cond_helper_mutex = NULL;
+#endif
+	pthread_setspecific(sTlsKey, &tls);
+
 	ok = 0 == pthread_mutex_init(&ctx->thread_mutex, NULL);
 	ok &= 0 == pthread_cond_init(&ctx->thread_cond, NULL);
 	ok &= 0 == pthread_cond_init(&ctx->sq_empty, NULL);
@@ -11290,6 +11298,7 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 		 * occur in practice. */
 		mg_cry(fc(ctx), "Cannot initialize thread synchronization objects");
 		mg_free(ctx);
+		pthread_setspecific(sTlsKey, NULL);
 		return NULL;
 	}
 
@@ -11309,10 +11318,12 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 		if ((idx = get_option_index(name)) == -1) {
 			mg_cry(fc(ctx), "Invalid option: %s", name);
 			free_context(ctx);
+			pthread_setspecific(sTlsKey, NULL);
 			return NULL;
 		} else if ((value = *options++) == NULL) {
 			mg_cry(fc(ctx), "%s: option value cannot be NULL", name);
 			free_context(ctx);
+			pthread_setspecific(sTlsKey, NULL);
 			return NULL;
 		}
 		if (ctx->config[idx] != NULL) {
@@ -11335,6 +11346,7 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 	if (ctx->config[DOCUMENT_ROOT] != NULL) {
 		mg_cry(fc(ctx), "%s", "Document root must not be set");
 		free_context(ctx);
+		pthread_setspecific(sTlsKey, NULL);
 		return NULL;
 	}
 #endif
@@ -11353,6 +11365,7 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 #endif
 	    !set_acl_option(ctx)) {
 		free_context(ctx);
+		pthread_setspecific(sTlsKey, NULL);
 		return NULL;
 	}
 
@@ -11367,6 +11380,7 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 	if (workerthreadcount > MAX_WORKER_THREADS) {
 		mg_cry(fc(ctx), "Too many worker threads");
 		free_context(ctx);
+		pthread_setspecific(sTlsKey, NULL);
 		return NULL;
 	}
 
@@ -11377,6 +11391,7 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 		if (ctx->workerthreadids == NULL) {
 			mg_cry(fc(ctx), "Not enough memory for worker thread ID array");
 			free_context(ctx);
+			pthread_setspecific(sTlsKey, NULL);
 			return NULL;
 		}
 	}
@@ -11385,6 +11400,7 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 	if (timers_init(ctx) != 0) {
 		mg_cry(fc(ctx), "Error creating timers");
 		free_context(ctx);
+		pthread_setspecific(sTlsKey, NULL);
 		return NULL;
 	}
 #endif
@@ -11418,12 +11434,14 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
 				mg_cry(
 				    fc(ctx), "Cannot create threads: error %ld", (long)ERRNO);
 				free_context(ctx);
+				pthread_setspecific(sTlsKey, NULL);
 				return NULL;
 			}
 			break;
 		}
 	}
 
+	pthread_setspecific(sTlsKey, NULL);
 	return ctx;
 }