Browse Source

Use eventfd instead of pthread_cond (step 2/?)

bel 9 năm trước cách đây
mục cha
commit
fd43dd37b1
1 tập tin đã thay đổi với 42 bổ sung5 xóa
  1. 42 5
      src/civetweb.c

+ 42 - 5
src/civetweb.c

@@ -1424,12 +1424,18 @@ struct mg_context {
 
 	pthread_mutex_t thread_mutex; /* Protects (max|num)_threads */
 
+#ifdef ALTERNATIVE_QUEUE
+	struct socket *client_socks;
+	int *client_wait_events;
+#else
 	struct socket queue[MGSQLEN]; /* Accepted sockets */
 	volatile int sq_head;         /* Head of the socket queue */
 	volatile int sq_tail;         /* Tail of the socket queue */
 	pthread_cond_t sq_full;       /* Signaled when socket is produced */
 	pthread_cond_t sq_empty;      /* Signaled when socket is consumed */
-	pthread_t masterthreadid;     /* The master thread ID */
+#endif
+
+	pthread_t masterthreadid; /* The master thread ID */
 	unsigned int
 	    cfg_worker_threads;     /* The number of configured worker threads. */
 	pthread_t *workerthreadids; /* The worker thread IDs */
@@ -12613,6 +12619,26 @@ process_new_connection(struct mg_connection *conn)
 }
 
 
+#if defined(ALTERNATIVE_QUEUE)
+
+static void
+produce_socket(struct mg_context *ctx, const struct socket *sp)
+{
+	unsigned int i;
+
+	for (i = 0; i < ctx->cfg_worker_threads; i++) {
+		/* TODO: find a free worker slot and signal it */
+	}
+}
+
+static int
+consume_socket(struct mg_context *ctx, struct socket *sp)
+{
+	/* TODO: every thread must wait for exactly one slot in the list */
+}
+
+#else /* ALTERNATIVE_QUEUE */
+
 /* Worker threads take accepted socket from the queue */
 static int
 consume_socket(struct mg_context *ctx, struct socket *sp)
@@ -12680,6 +12706,7 @@ produce_socket(struct mg_context *ctx, const struct socket *sp)
 	(void)pthread_mutex_unlock(&ctx->thread_mutex);
 #undef QUEUE_SIZE
 }
+#endif /* ALTERNATIVE_QUEUE */
 
 
 static void *
@@ -12957,7 +12984,12 @@ master_thread_run(void *thread_func_param)
 
 	/* Wakeup workers that are waiting for connections to handle. */
 	(void)pthread_mutex_lock(&ctx->thread_mutex);
+#if defined(ALTERNATIVE_QUEUE)
+/* TODO: signal all workers */
+/* TODO: close all socket handles (will avoid SOCKET_TIMEOUT_QUANTUM) */
+#else
 	pthread_cond_broadcast(&ctx->sq_full);
+#endif
 	(void)pthread_mutex_unlock(&ctx->thread_mutex);
 
 	/* Join all worker threads to avoid leaking threads. */
@@ -13022,8 +13054,12 @@ free_context(struct mg_context *ctx)
 	 * condvars
 	 */
 	(void)pthread_mutex_destroy(&ctx->thread_mutex);
+#if defined(ALTERNATIVE_QUEUE)
+/* TODO: free allocated memory */
+#else
 	(void)pthread_cond_destroy(&ctx->sq_empty);
 	(void)pthread_cond_destroy(&ctx->sq_full);
+#endif
 
 	/* Destroy other context global data structures mutex */
 	(void)pthread_mutex_destroy(&ctx->nonce_mutex);
@@ -13102,10 +13138,7 @@ mg_stop(struct mg_context *ctx)
 	/* Set stop flag, so all threads know they have to exit. */
 	ctx->stop_flag = 1;
 
-	/* TODO: close all socket handles (will avoid SOCKET_TIMEOUT_QUANTUM) */
-
-
-	/* Wait until mg_fini() stops */
+	/* Wait until everything has stopped. */
 	while (ctx->stop_flag != 2) {
 		(void)mg_sleep(10);
 	}
@@ -13230,8 +13263,12 @@ mg_start(const struct mg_callbacks *callbacks,
 #endif
 
 	ok = 0 == pthread_mutex_init(&ctx->thread_mutex, &pthread_mutex_attr);
+#if defined(ALTERNATIVE_QUEUE)
+/* TODO: allocate memory */
+#else
 	ok &= 0 == pthread_cond_init(&ctx->sq_empty, NULL);
 	ok &= 0 == pthread_cond_init(&ctx->sq_full, NULL);
+#endif
 	ok &= 0 == pthread_mutex_init(&ctx->nonce_mutex, &pthread_mutex_attr);
 	if (!ok) {
 		/* Fatal error - abort start. However, this situation should never