|
@@ -1424,12 +1424,18 @@ struct mg_context {
|
|
|
|
|
|
pthread_mutex_t thread_mutex; /* Protects (max|num)_threads */
|
|
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 */
|
|
struct socket queue[MGSQLEN]; /* Accepted sockets */
|
|
volatile int sq_head; /* Head of the socket queue */
|
|
volatile int sq_head; /* Head of the socket queue */
|
|
volatile int sq_tail; /* Tail 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_full; /* Signaled when socket is produced */
|
|
pthread_cond_t sq_empty; /* Signaled when socket is consumed */
|
|
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
|
|
unsigned int
|
|
cfg_worker_threads; /* The number of configured worker threads. */
|
|
cfg_worker_threads; /* The number of configured worker threads. */
|
|
pthread_t *workerthreadids; /* The worker thread IDs */
|
|
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 */
|
|
/* Worker threads take accepted socket from the queue */
|
|
static int
|
|
static int
|
|
consume_socket(struct mg_context *ctx, struct socket *sp)
|
|
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);
|
|
(void)pthread_mutex_unlock(&ctx->thread_mutex);
|
|
#undef QUEUE_SIZE
|
|
#undef QUEUE_SIZE
|
|
}
|
|
}
|
|
|
|
+#endif /* ALTERNATIVE_QUEUE */
|
|
|
|
|
|
|
|
|
|
static void *
|
|
static void *
|
|
@@ -12957,7 +12984,12 @@ master_thread_run(void *thread_func_param)
|
|
|
|
|
|
/* Wakeup workers that are waiting for connections to handle. */
|
|
/* Wakeup workers that are waiting for connections to handle. */
|
|
(void)pthread_mutex_lock(&ctx->thread_mutex);
|
|
(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);
|
|
pthread_cond_broadcast(&ctx->sq_full);
|
|
|
|
+#endif
|
|
(void)pthread_mutex_unlock(&ctx->thread_mutex);
|
|
(void)pthread_mutex_unlock(&ctx->thread_mutex);
|
|
|
|
|
|
/* Join all worker threads to avoid leaking threads. */
|
|
/* Join all worker threads to avoid leaking threads. */
|
|
@@ -13022,8 +13054,12 @@ free_context(struct mg_context *ctx)
|
|
* condvars
|
|
* condvars
|
|
*/
|
|
*/
|
|
(void)pthread_mutex_destroy(&ctx->thread_mutex);
|
|
(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_empty);
|
|
(void)pthread_cond_destroy(&ctx->sq_full);
|
|
(void)pthread_cond_destroy(&ctx->sq_full);
|
|
|
|
+#endif
|
|
|
|
|
|
/* Destroy other context global data structures mutex */
|
|
/* Destroy other context global data structures mutex */
|
|
(void)pthread_mutex_destroy(&ctx->nonce_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. */
|
|
/* Set stop flag, so all threads know they have to exit. */
|
|
ctx->stop_flag = 1;
|
|
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) {
|
|
while (ctx->stop_flag != 2) {
|
|
(void)mg_sleep(10);
|
|
(void)mg_sleep(10);
|
|
}
|
|
}
|
|
@@ -13230,8 +13263,12 @@ mg_start(const struct mg_callbacks *callbacks,
|
|
#endif
|
|
#endif
|
|
|
|
|
|
ok = 0 == pthread_mutex_init(&ctx->thread_mutex, &pthread_mutex_attr);
|
|
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_empty, NULL);
|
|
ok &= 0 == pthread_cond_init(&ctx->sq_full, NULL);
|
|
ok &= 0 == pthread_cond_init(&ctx->sq_full, NULL);
|
|
|
|
+#endif
|
|
ok &= 0 == pthread_mutex_init(&ctx->nonce_mutex, &pthread_mutex_attr);
|
|
ok &= 0 == pthread_mutex_init(&ctx->nonce_mutex, &pthread_mutex_attr);
|
|
if (!ok) {
|
|
if (!ok) {
|
|
/* Fatal error - abort start. However, this situation should never
|
|
/* Fatal error - abort start. However, this situation should never
|