From a7080226f89db7342cfd70adec3a87813d2389fe Mon Sep 17 00:00:00 2001 From: bel2125 Date: Fri, 27 Nov 2015 20:09:02 +0100 Subject: [PATCH] Fix websockets for Lua for Linux Websockets for Lua only works if the used mutex is recursive --- src/mod_lua.inl | 88 ++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/src/mod_lua.inl b/src/mod_lua.inl index c7a49a7c..b0c9dd77 100644 --- a/src/mod_lua.inl +++ b/src/mod_lua.inl @@ -852,9 +852,9 @@ lwebsock_write(lua_State *L) lua_gettable(L, LUA_REGISTRYINDEX); ws = (struct lua_websock_data *)lua_touserdata(L, -1); -printf("wwwww lock == %p)\n", ws); +printf("%p wwwww lock == %p)\n", pthread_self(), ws); (void)pthread_mutex_lock(&(ws->ws_mutex)); -printf("wwwww locked == %p)\n", ws); +printf("%p wwwww locked == %p)\n", pthread_self(), ws); if (num_args == 1) { /* just one text: send it to all client */ @@ -924,15 +924,15 @@ printf("wwwww locked == %p)\n", ws); } } } else { -printf("wwwwwerr unlock == %p)\n", ws); +printf("%p wwwwwerr unlock == %p)\n", pthread_self(), ws); (void)pthread_mutex_unlock(&(ws->ws_mutex)); -printf("wwwwwerr unlocked == %p)\n", ws); +printf("%p wwwwwerr unlocked == %p)\n", pthread_self(), ws); return luaL_error(L, "invalid websocket write() call"); } -printf("wwwww unlock == %p)\n", ws); +printf("%p wwwww unlock == %p)\n", pthread_self(), ws); (void)pthread_mutex_unlock(&(ws->ws_mutex)); -printf("wwwww unlocked == %p)\n", ws); +printf("%p wwwww unlocked == %p)\n", pthread_self(), ws); #else (void)(L); /* unused */ @@ -953,9 +953,9 @@ lua_action(struct laction_arg *arg) int err, ok; struct mg_context *ctx; -printf("action lock %p\n", arg->pmutex); +printf("%p action lock %p\n", pthread_self(), arg->pmutex); (void)pthread_mutex_lock(arg->pmutex); -printf("action locked %p\n", arg->pmutex); +printf("%p action locked %p\n", pthread_self(), arg->pmutex); lua_pushlightuserdata(arg->state, (void *)&lua_regkey_ctx); lua_gettable(arg->state, LUA_REGISTRYINDEX); @@ -964,18 +964,18 @@ printf("action locked %p\n", arg->pmutex); err = luaL_loadstring(arg->state, arg->txt); if (err != 0) { lua_cry(fc(ctx), err, arg->state, arg->script, "timer"); -printf("action unlock1 %p\n", arg->pmutex); +printf("%p action unlock1 %p\n", pthread_self(), arg->pmutex); (void)pthread_mutex_unlock(arg->pmutex); -printf("action unlocked1 %p\n", arg->pmutex); +printf("%p action unlocked1 %p\n", pthread_self(), arg->pmutex); mg_free(arg); return 0; } err = lua_pcall(arg->state, 0, 1, 0); if (err != 0) { lua_cry(fc(ctx), err, arg->state, arg->script, "timer"); -printf("action unlock2 %p\n", arg->pmutex); +printf("%p action unlock2 %p\n", pthread_self(), arg->pmutex); (void)pthread_mutex_unlock(arg->pmutex); -printf("action unlocked2 %p\n", arg->pmutex); +printf("%p action unlocked2 %p\n", pthread_self(), arg->pmutex); mg_free(arg); return 0; } @@ -988,9 +988,9 @@ printf("action unlocked2 %p\n", arg->pmutex); } lua_pop(arg->state, 1); -printf("action unlockX %p\n", arg->pmutex); +printf("%p action unlockX %p\n", pthread_self(), arg->pmutex); (void)pthread_mutex_unlock(arg->pmutex); -printf("action unlockedX %p\n", arg->pmutex); +printf("%p action unlockedX %p\n", pthread_self(), arg->pmutex); if (!ok) { mg_free(arg); @@ -1236,15 +1236,15 @@ prepare_lua_environment(struct mg_context *ctx, switch (lua_env_type) { case LUA_ENV_TYPE_LUA_SERVER_PAGE: reg_string(L, "lua_type", "page"); -printf(">Y>Y>Y page\n"); +printf("%p >Y>Y>Y page\n", pthread_self()); break; case LUA_ENV_TYPE_PLAIN_LUA_PAGE: reg_string(L, "lua_type", "script"); -printf(">Y>Y>Y script\n"); +printf("%p >Y>Y>Y script\n", pthread_self()); break; case LUA_ENV_TYPE_LUA_WEBSOCKET: reg_string(L, "lua_type", "websocket"); -printf(">Y>Y>Y websocket\n"); +printf("%p >Y>Y>Y websocket\n", pthread_self()); break; } @@ -1498,7 +1498,7 @@ lua_websocket_new(const char *script, struct mg_connection *conn) assert(conn->lua_websocket_state == NULL); -printf("XXXXX lua_websocket_new(%s, %p)\n", script, conn); +printf("%p XXXXX lua_websocket_new(%s, %p)\n", pthread_self(), script, conn); /* lock list (mg_context global) */ mg_lock_context(conn->ctx); @@ -1510,7 +1510,7 @@ printf("XXXXX lua_websocket_new(%s, %p)\n", script, conn); shared_websock_list = &((*shared_websock_list)->next); } -printf("XXXXX shared_websock_list == %p)\n", shared_websock_list); +printf("%p XXXXX shared_websock_list == %p)\n", pthread_self(), shared_websock_list); if (*shared_websock_list == NULL) { /* add ws to list */ @@ -1524,10 +1524,10 @@ printf("XXXXX shared_websock_list == %p)\n", shared_websock_list); /* init ws list element */ ws = &(*shared_websock_list)->ws; ws->script = mg_strdup(script); /* TODO (low): handle OOM */ - pthread_mutex_init(&(ws->ws_mutex), NULL); -printf("XXXXX lock == %p)\n", ws); + pthread_mutex_init(&(ws->ws_mutex), &pthread_mutex_attr); +printf("%p XXXXX lock == %p)\n", pthread_self(), ws); (void)pthread_mutex_lock(&(ws->ws_mutex)); -printf("XXXXX locked == %p)\n", ws); +printf("%p XXXXX locked == %p)\n", pthread_self(), ws); ws->state = lua_newstate(lua_allocator, NULL); ws->conn[0] = conn; ws->references = 1; @@ -1544,14 +1544,14 @@ printf("XXXXX locked == %p)\n", ws); } else { /* inc ref count */ ws = &(*shared_websock_list)->ws; -printf("XXXXX lock == %p)\n", ws); +printf("%p XXXXX lock == %p)\n", pthread_self(), ws); (void)pthread_mutex_lock(&(ws->ws_mutex)); -printf("XXXXX locked == %p)\n", ws); +printf("%p XXXXX locked == %p)\n", pthread_self(), ws); (*shared_websock_list)->ws.conn[(ws->references)++] = conn; } mg_unlock_context(conn->ctx); -printf("XXXXX ws == %p)\n", ws); +printf("%p XXXXX ws == %p)\n", pthread_self(), ws); /* call add */ lua_getglobal(ws->state, "open"); @@ -1561,7 +1561,7 @@ printf("XXXXX ws == %p)\n", ws); lua_pushlightuserdata(ws->state, (void *)conn); lua_rawset(ws->state, -3); -printf("XXXXX lua_pcall == %p)\n", ws->state); +printf("%p XXXXX lua_pcall == %p)\n", pthread_self(), ws->state); err = lua_pcall(ws->state, 1, 1, 0); if (err != 0) { @@ -1579,9 +1579,9 @@ printf("XXXXX lua_pcall == %p)\n", ws->state); (*shared_websock_list)->ws.conn[--(ws->references)] = 0; } -printf("XXXXX unlock == %p)\n", ws); +printf("%p XXXXX unlock == %p)\n", pthread_self(), ws); (void)pthread_mutex_unlock(&(ws->ws_mutex)); -printf("XXXXX unlocked == %p)\n", ws); +printf("%p XXXXX unlocked == %p)\n", pthread_self(), ws); return ok ? (void *)ws : NULL; } @@ -1599,9 +1599,9 @@ lua_websocket_data(struct mg_connection *conn, assert(ws != NULL); assert(ws->state != NULL); -printf("ddddd lock == %p)\n", ws); +printf("%p ddddd lock == %p)\n", pthread_self(), ws); (void)pthread_mutex_lock(&(ws->ws_mutex)); -printf("ddddd locked == %p)\n", ws); +printf("%p ddddd locked == %p)\n", pthread_self(), ws); lua_getglobal(ws->state, "data"); lua_newtable(ws->state); @@ -1627,9 +1627,9 @@ printf("ddddd locked == %p)\n", ws); } lua_pop(ws->state, 1); } -printf("ddddd unlock == %p)\n", ws); +printf("%p ddddd unlock == %p)\n", pthread_self(), ws); (void)pthread_mutex_unlock(&(ws->ws_mutex)); -printf("ddddd unlocked == %p)\n", ws); +printf("%p ddddd unlocked == %p)\n", pthread_self(), ws); return ok; } @@ -1643,29 +1643,35 @@ lua_websocket_ready(struct mg_connection *conn, void *ws_arg) assert(ws != NULL); assert(ws->state != NULL); -printf("rrrrr lock == %p)\n", ws); +printf("%p rrrrr lock == %p)\n", pthread_self(), ws); (void)pthread_mutex_lock(&(ws->ws_mutex)); -printf("rrrrr locked == %p)\n", ws); +printf("%p rrrrr locked == %p)\n", pthread_self(), ws); lua_getglobal(ws->state, "ready"); lua_newtable(ws->state); lua_pushstring(ws->state, "client"); lua_pushlightuserdata(ws->state, (void *)conn); lua_rawset(ws->state, -3); - +printf("r2\n"); err = lua_pcall(ws->state, 1, 1, 0); +printf("r3\n"); if (err != 0) { +printf("r4\n"); lua_cry(conn, err, ws->state, ws->script, "ready handler"); +printf("r5\n"); } else { +printf("r6\n"); if (lua_isboolean(ws->state, -1)) { ok = lua_toboolean(ws->state, -1); } +printf("r7\n"); lua_pop(ws->state, 1); +printf("r8\n"); } -printf("rrrrr unlock == %p)\n", ws); +printf("%p rrrrr unlock == %p)\n", pthread_self(), ws); (void)pthread_mutex_unlock(&(ws->ws_mutex)); -printf("rrrrr unlocked == %p)\n", ws); +printf("%p rrrrr unlocked == %p)\n", pthread_self(), ws); return ok; } @@ -1682,9 +1688,9 @@ lua_websocket_close(struct mg_connection *conn, void *ws_arg) assert(ws != NULL); assert(ws->state != NULL); -printf("ccccc lock == %p)\n", ws); +printf("%p ccccc lock == %p)\n", pthread_self(), ws); (void)pthread_mutex_lock(&(ws->ws_mutex)); -printf("ccccc locked == %p)\n", ws); +printf("%p ccccc locked == %p)\n", pthread_self(), ws); lua_getglobal(ws->state, "close"); lua_newtable(ws->state); @@ -1707,8 +1713,8 @@ printf("ccccc locked == %p)\n", ws); asynchronous operations and timers are completed/expired. */ (void)shared_websock_list; /* shared_websock_list unused (see open TODO) */ -printf("ccccc unlock == %p)\n", ws); +printf("%p ccccc unlock == %p)\n", pthread_self(), ws); (void)pthread_mutex_unlock(&(ws->ws_mutex)); -printf("ccccc unlocked == %p)\n", ws); +printf("%p ccccc unlocked == %p)\n", pthread_self(), ws); } #endif