From 00b289a0f4efbce3c2b40e7e2a7243f3c400f8a9 Mon Sep 17 00:00:00 2001
From: Sergey Lyubka <valenok@gmail.com>
Date: Mon, 26 Aug 2013 12:22:38 +0100
Subject: [PATCH] Added thread_start() and thread_stop()

---
 mongoose.c | 18 ++++++++++++++++++
 mongoose.h | 21 +++++++++++++++++----
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/mongoose.c b/mongoose.c
index a8d43d74f..b31c57642 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -5134,6 +5134,11 @@ static void *worker_thread(void *thread_func_param) {
     conn->ctx = ctx;
     conn->request_info.user_data = ctx->user_data;
 
+    if (ctx->callbacks.thread_start != NULL) {
+      ctx->callbacks.thread_start(&conn->request_info.user_data,
+                                  &conn->request_info.conn_data);
+    }
+
     // 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)) {
@@ -5160,6 +5165,11 @@ static void *worker_thread(void *thread_func_param) {
       close_connection(conn);
     }
     free(conn);
+
+    if (ctx->callbacks.thread_stop != NULL) {
+      ctx->callbacks.thread_stop(&conn->request_info.user_data,
+                                     &conn->request_info.conn_data);
+    }
   }
 
   // Signal master that we're done with connection and exiting
@@ -5253,6 +5263,10 @@ static void *master_thread(void *thread_func_param) {
   pthread_setschedparam(pthread_self(), SCHED_RR, &sched_param);
 #endif
 
+  if (ctx->callbacks.thread_start != NULL) {
+    ctx->callbacks.thread_start(&ctx->user_data, NULL);
+  }
+
   pfd = (struct pollfd *) calloc(ctx->num_listening_sockets, sizeof(pfd[0]));
   while (pfd != NULL && ctx->stop_flag == 0) {
     for (i = 0; i < ctx->num_listening_sockets; i++) {
@@ -5299,6 +5313,10 @@ static void *master_thread(void *thread_func_param) {
 #endif
   DEBUG_TRACE(("exiting"));
 
+  if (ctx->callbacks.thread_stop != NULL) {
+    ctx->callbacks.thread_stop(&ctx->user_data, NULL);
+  }
+
   // Signal mg_stop() that we're done.
   // WARNING: This must be the very last thing this
   // thread does, as ctx becomes invalid after this line.
diff --git a/mongoose.h b/mongoose.h
index 6a50e38da..0d9239558 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -40,7 +40,7 @@ struct mg_request_info {
   int remote_port;            // Client's port
   int is_ssl;                 // 1 if SSL-ed, 0 if not
   void *user_data;            // User data pointer passed to mg_start()
-  void *conn_data;            // Connection-specific user data
+  void *conn_data;            // Connection-specific, per-thread user data.
 
   int num_headers;            // Number of HTTP headers
   struct mg_header {
@@ -116,10 +116,23 @@ struct mg_callbacks {
   //    file_file: full path name to the uploaded file.
   void (*upload)(struct mg_connection *, const char *file_name);
 
-  // Called when mongoose is about to send HTTP error to the client.
-  // Implementing this callback allows to create custom error pages.
+  // Called at the beginning of mongoose's thread execution in the context of
+  // that thread. To be used to perform any extra per-thread initialization.
   // Parameters:
-  //   status: HTTP error status code.
+  //  user_data: pointer passed to mg_start
+  //  conn_data: per-connection, i.e. per-thread pointer. Can be used to
+  //             store per-thread data, for example, database connection
+  //             handles. Persistent between connections handled by the
+  //             same thread.
+  //             NOTE: this parameter is NULL for master thread, and non-NULL
+  //             for worker threads.
+  void (*thread_start)(void *user_data, void **conn_data);
+
+  // Called when mongoose's thread is about to terminate.
+  // Same as thread_setup() callback, but called when thread is about to be
+  // destroyed. Used to cleanup the state initialized by thread_setup().
+  // Parameters: see thread_start().
+  void (*thread_stop)(void *user_data, void **conn_data);
 };
 
 // Start web server.
-- 
GitLab