From 0a3cb63c73b553555c68b218c2ccda618333c31c Mon Sep 17 00:00:00 2001
From: Sergey Lyubka <valenok@gmail.com>
Date: Sat, 1 Mar 2014 01:47:01 +0000
Subject: [PATCH] Added mg_wakeup_server()

---
 mongoose.c | 37 ++++++++++++++++++++++++++-----------
 mongoose.h |  1 +
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/mongoose.c b/mongoose.c
index 681eacba9..40d965a18 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -69,6 +69,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <signal.h>
 
 #ifdef _WIN32
 #pragma comment(lib, "ws2_32.lib")    // Linking with winsock library
@@ -103,7 +104,6 @@ typedef SOCKET sock_t;
 #include <fcntl.h>
 #include <netdb.h>
 #include <pthread.h>
-#include <signal.h>
 #include <stdarg.h>
 #include <unistd.h>
 #include <arpa/inet.h>  // For inet_pton() when NS_ENABLE_IPV6 is defined
@@ -171,6 +171,7 @@ struct ns_server {
   ns_callback_t callback;
   SSL_CTX *ssl_ctx;
   SSL_CTX *client_ssl_ctx;
+  sock_t ctl[2];
 };
 
 struct ns_connection {
@@ -198,7 +199,7 @@ struct ns_connection {
 void ns_server_init(struct ns_server *, void *server_data, ns_callback_t);
 void ns_server_free(struct ns_server *);
 int ns_server_poll(struct ns_server *, int milli);
-void ns_server_wakeup(struct ns_server *, void *conn_param);
+void ns_server_wakeup(struct ns_server *);
 void ns_iterate(struct ns_server *, ns_callback_t cb, void *param);
 struct ns_connection *ns_add_sock(struct ns_server *, sock_t sock, void *p);
 
@@ -901,9 +902,17 @@ void ns_iterate(struct ns_server *server, ns_callback_t cb, void *param) {
   }
 }
 
+void ns_server_wakeup(struct ns_server *server) {
+  unsigned char ch = 0;
+  if (server->ctl[0] != INVALID_SOCKET) {
+    send(server->ctl[0], &ch, 1, 0);
+    recv(server->ctl[0], &ch, 1, 0);
+  }
+}
+
 void ns_server_init(struct ns_server *s, void *server_data, ns_callback_t cb) {
   memset(s, 0, sizeof(*s));
-  s->listening_sock = INVALID_SOCKET;
+  s->listening_sock = s->ctl[0] = s->ctl[1] = INVALID_SOCKET;
   s->server_data = server_data;
   s->callback = cb;
 
@@ -915,6 +924,12 @@ void ns_server_init(struct ns_server *s, void *server_data, ns_callback_t cb) {
   signal(SIGPIPE, SIG_IGN);
 #endif
 
+#ifndef NS_DISABLE_SOCKETPAIR
+  do {
+    ns_socketpair(s->ctl);
+  } while (s->ctl[0] == INVALID_SOCKET);
+#endif
+
 #ifdef NS_ENABLE_SSL
   SSL_library_init();
   s->client_ssl_ctx = SSL_CTX_new(SSLv23_client_method());
@@ -929,20 +944,16 @@ void ns_server_free(struct ns_server *s) {
   // Do one last poll, see https://github.com/cesanta/mongoose/issues/286
   ns_server_poll(s, 0);
 
-  if (s->listening_sock != INVALID_SOCKET) {
-    closesocket(s->listening_sock);
-  }
+  if (s->listening_sock != INVALID_SOCKET) closesocket(s->listening_sock);
+  if (s->ctl[0] != INVALID_SOCKET) closesocket(s->ctl[0]);
+  if (s->ctl[1] != INVALID_SOCKET) closesocket(s->ctl[1]);
+  s->listening_sock = s->ctl[0] = s->ctl[1] = INVALID_SOCKET;
 
   for (conn = s->active_connections; conn != NULL; conn = tmp_conn) {
     tmp_conn = conn->next;
     ns_close_conn(conn);
   }
 
-#ifndef NS_DISABLE_SOCKETPAIR
-  //closesocket(s->ctl[0]);
-  //closesocket(s->ctl[1]);
-#endif
-
 #ifdef NS_ENABLE_SSL
   if (s->ssl_ctx != NULL) SSL_CTX_free(s->ssl_ctx);
   if (s->client_ssl_ctx != NULL) SSL_CTX_free(s->client_ssl_ctx);
@@ -4614,6 +4625,10 @@ static void mg_ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) {
   }
 }
 
+void mg_wakeup_server(struct mg_server *server) {
+  ns_server_wakeup(&server->ns_server);
+}
+
 void mg_set_listening_socket(struct mg_server *server, int sock) {
   if (server->ns_server.listening_sock != INVALID_SOCKET) {
     closesocket(server->ns_server.listening_sock);
diff --git a/mongoose.h b/mongoose.h
index 4426cac6f..6a6c881f8 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -80,6 +80,7 @@ const char *mg_get_option(const struct mg_server *server, const char *name);
 void mg_set_listening_socket(struct mg_server *, int sock);
 int mg_get_listening_socket(struct mg_server *);
 void mg_iterate_over_connections(struct mg_server *, mg_handler_t);
+void mg_wakeup_server(struct mg_server *);
 
 // Connection management functions
 void mg_send_status(struct mg_connection *, int status_code);
-- 
GitLab