Parcourir la source

Prepare shared Lua Websockets

bel il y a 11 ans
Parent
commit
38bbd731f4
2 fichiers modifiés avec 72 ajouts et 8 suppressions
  1. 10 3
      src/civetweb.c
  2. 62 5
      src/mod_lua.inl

+ 10 - 3
src/civetweb.c

@@ -651,6 +651,11 @@ struct mg_context {
 
     /* linked list of uri handlers */
     struct mg_request_handler_info *request_handlers;
+
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+    /* linked list of shared lua websockets */
+    struct mg_shared_lua_websocket *shared_lua_websockets;
+#endif
 };
 
 struct mg_connection {
@@ -4967,6 +4972,7 @@ static void handle_websocket_request(struct mg_connection *conn, const char *pat
                                        path) : 0;
 
         if (lua_websock || shared_lua_websock) {
+            /* TODO */ shared_lua_websock=1;
             conn->lua_websocket_state = lua_websocket_new(path, conn, !!shared_lua_websock);
             if (conn->lua_websocket_state) {
                 send_websocket_handshake(conn);
@@ -5951,9 +5957,6 @@ void mg_close_connection(struct mg_connection *conn)
 }
 
 struct mg_connection *mg_connect(const char *host, int port, int use_ssl,
-                                 char *ebuf, size_t ebuf_len);
-
-struct mg_connection *mg_connect(const char *host, int port, int use_ssl,
                                  char *ebuf, size_t ebuf_len)
 {
     static struct mg_context fake_ctx;
@@ -6566,6 +6569,10 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
     ctx->user_data = user_data;
     ctx->request_handlers = 0;
 
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+    ctx->shared_lua_websockets = 0;
+#endif
+
     while (options && (name = *options++) != NULL) {
         if ((i = get_option_index(name)) == -1) {
             mg_cry(fc(ctx), "Invalid option: %s", name);

+ 62 - 5
src/mod_lua.inl

@@ -909,9 +909,16 @@ struct file *filep, struct lua_State *ls)
 struct lua_websock_data {
     lua_State *main;
     lua_State *thread;
+    char * script;
+    unsigned shared;
     struct mg_connection *conn;
 };
 
+struct mg_shared_lua_websocket {
+    struct lua_websock_data *sock;
+    struct mg_shared_lua_websocket *next;
+};
+
 static void websock_cry(struct mg_connection *conn, int err, lua_State * L, const char * ws_operation, const char * lua_operation)
 {
     switch (err) {
@@ -942,18 +949,46 @@ static void websock_cry(struct mg_connection *conn, int err, lua_State * L, cons
 static void * lua_websocket_new(const char * script, struct mg_connection *conn, int is_shared)
 {
     struct lua_websock_data *lws_data;
+    struct mg_shared_lua_websocket **shared_websock_list = &(conn->ctx->shared_lua_websockets);
     int ok = 0;
+    int found = 0;
     int err, nargs;
 
     assert(conn->lua_websocket_state == NULL);
-    lws_data = (struct lua_websock_data *) malloc(sizeof(*lws_data));
+
+    if (is_shared) {
+        (void)pthread_mutex_lock(&conn->ctx->mutex);
+        while (*shared_websock_list) {
+            if (!strcmp((*shared_websock_list)->sock->script, script)) {
+                lws_data = (*shared_websock_list)->sock;
+                lws_data->shared++;
+                found = 1;
+            }
+            shared_websock_list = &((*shared_websock_list)->next);
+        }
+        (void)pthread_mutex_unlock(&conn->ctx->mutex);
+    }
+
+    if (!found) {
+        lws_data = (struct lua_websock_data *) malloc(sizeof(*lws_data));
+        lws_data->shared = is_shared;
+    }
 
     if (lws_data) {
         lws_data->conn = conn;
+        lws_data->script = mg_strdup(script);
 
-        if (is_shared) {
+        if (is_shared && !found) {
             (void)pthread_mutex_lock(&conn->ctx->mutex);
-            // TODO: add_to_websocket_list(lws_data);
+            shared_websock_list = &(conn->ctx->shared_lua_websockets);
+            while (*shared_websock_list) {
+                shared_websock_list = &((*shared_websock_list)->next);
+            }
+            *shared_websock_list = (struct mg_shared_lua_websocket *)malloc(sizeof(struct mg_shared_lua_websocket));
+            if (*shared_websock_list) {
+                (*shared_websock_list)->sock = lws_data;
+                (*shared_websock_list)->next = 0;
+            }
             (void)pthread_mutex_unlock(&conn->ctx->mutex);
         }
 
@@ -1054,6 +1089,7 @@ static int lua_websocket_ready(struct mg_connection *conn)
 static void lua_websocket_close(struct mg_connection *conn)
 {
     struct lua_websock_data *lws_data = (struct lua_websock_data *)(conn->lua_websocket_state);
+    struct mg_shared_lua_websocket **shared_websock_list;
     int err;
 
     assert(lws_data != NULL);
@@ -1063,8 +1099,29 @@ static void lua_websocket_close(struct mg_connection *conn)
     lua_pushboolean(lws_data->thread, 0);
     err = lua_resume(lws_data->thread, NULL, 1);
 
-    lua_close(lws_data->main);
-    free(lws_data);
+    if (lws_data->shared) {
+        (void)pthread_mutex_lock(&conn->ctx->mutex);
+        lws_data->shared--;
+        if (lws_data->shared==0) {
+            shared_websock_list = &(conn->ctx->shared_lua_websockets);
+            while (*shared_websock_list) {
+                if ((*shared_websock_list)->sock == lws_data) {
+                    *shared_websock_list = (*shared_websock_list)->next;
+                } else {
+                    shared_websock_list = &((*shared_websock_list)->next);
+                }
+            }
+
+            lua_close(lws_data->main);
+            free(lws_data->script);
+            lws_data->script=0;
+            free(lws_data);
+        }
+        (void)pthread_mutex_unlock(&conn->ctx->mutex);
+    } else {
+        lua_close(lws_data->main);
+        free(lws_data);
+    }
     conn->lua_websocket_state = NULL;
 }
 #endif