1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-12-22 04:02:04 +03:00

Fix websockets for Lua for Linux

Websockets for Lua only works if the used mutex is recursive
This commit is contained in:
bel2125
2015-11-27 20:09:02 +01:00
parent 1473a00ce2
commit a7080226f8

View File

@@ -852,9 +852,9 @@ lwebsock_write(lua_State *L)
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
ws = (struct lua_websock_data *)lua_touserdata(L, -1); 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)); (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) { if (num_args == 1) {
/* just one text: send it to all client */ /* just one text: send it to all client */
@@ -924,15 +924,15 @@ printf("wwwww locked == %p)\n", ws);
} }
} }
} else { } else {
printf("wwwwwerr unlock == %p)\n", ws); printf("%p wwwwwerr unlock == %p)\n", pthread_self(), ws);
(void)pthread_mutex_unlock(&(ws->ws_mutex)); (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"); 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)); (void)pthread_mutex_unlock(&(ws->ws_mutex));
printf("wwwww unlocked == %p)\n", ws); printf("%p wwwww unlocked == %p)\n", pthread_self(), ws);
#else #else
(void)(L); /* unused */ (void)(L); /* unused */
@@ -953,9 +953,9 @@ lua_action(struct laction_arg *arg)
int err, ok; int err, ok;
struct mg_context *ctx; 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); (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_pushlightuserdata(arg->state, (void *)&lua_regkey_ctx);
lua_gettable(arg->state, LUA_REGISTRYINDEX); lua_gettable(arg->state, LUA_REGISTRYINDEX);
@@ -964,18 +964,18 @@ printf("action locked %p\n", arg->pmutex);
err = luaL_loadstring(arg->state, arg->txt); err = luaL_loadstring(arg->state, arg->txt);
if (err != 0) { if (err != 0) {
lua_cry(fc(ctx), err, arg->state, arg->script, "timer"); 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); (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); mg_free(arg);
return 0; return 0;
} }
err = lua_pcall(arg->state, 0, 1, 0); err = lua_pcall(arg->state, 0, 1, 0);
if (err != 0) { if (err != 0) {
lua_cry(fc(ctx), err, arg->state, arg->script, "timer"); 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); (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); mg_free(arg);
return 0; return 0;
} }
@@ -988,9 +988,9 @@ printf("action unlocked2 %p\n", arg->pmutex);
} }
lua_pop(arg->state, 1); 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); (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) { if (!ok) {
mg_free(arg); mg_free(arg);
@@ -1236,15 +1236,15 @@ prepare_lua_environment(struct mg_context *ctx,
switch (lua_env_type) { switch (lua_env_type) {
case LUA_ENV_TYPE_LUA_SERVER_PAGE: case LUA_ENV_TYPE_LUA_SERVER_PAGE:
reg_string(L, "lua_type", "page"); reg_string(L, "lua_type", "page");
printf(">Y>Y>Y page\n"); printf("%p >Y>Y>Y page\n", pthread_self());
break; break;
case LUA_ENV_TYPE_PLAIN_LUA_PAGE: case LUA_ENV_TYPE_PLAIN_LUA_PAGE:
reg_string(L, "lua_type", "script"); reg_string(L, "lua_type", "script");
printf(">Y>Y>Y script\n"); printf("%p >Y>Y>Y script\n", pthread_self());
break; break;
case LUA_ENV_TYPE_LUA_WEBSOCKET: case LUA_ENV_TYPE_LUA_WEBSOCKET:
reg_string(L, "lua_type", "websocket"); reg_string(L, "lua_type", "websocket");
printf(">Y>Y>Y websocket\n"); printf("%p >Y>Y>Y websocket\n", pthread_self());
break; break;
} }
@@ -1498,7 +1498,7 @@ lua_websocket_new(const char *script, struct mg_connection *conn)
assert(conn->lua_websocket_state == NULL); 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) */ /* lock list (mg_context global) */
mg_lock_context(conn->ctx); 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); 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) { if (*shared_websock_list == NULL) {
/* add ws to list */ /* add ws to list */
@@ -1524,10 +1524,10 @@ printf("XXXXX shared_websock_list == %p)\n", shared_websock_list);
/* init ws list element */ /* init ws list element */
ws = &(*shared_websock_list)->ws; ws = &(*shared_websock_list)->ws;
ws->script = mg_strdup(script); /* TODO (low): handle OOM */ ws->script = mg_strdup(script); /* TODO (low): handle OOM */
pthread_mutex_init(&(ws->ws_mutex), NULL); pthread_mutex_init(&(ws->ws_mutex), &pthread_mutex_attr);
printf("XXXXX lock == %p)\n", ws); printf("%p XXXXX lock == %p)\n", pthread_self(), ws);
(void)pthread_mutex_lock(&(ws->ws_mutex)); (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->state = lua_newstate(lua_allocator, NULL);
ws->conn[0] = conn; ws->conn[0] = conn;
ws->references = 1; ws->references = 1;
@@ -1544,14 +1544,14 @@ printf("XXXXX locked == %p)\n", ws);
} else { } else {
/* inc ref count */ /* inc ref count */
ws = &(*shared_websock_list)->ws; 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)); (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; (*shared_websock_list)->ws.conn[(ws->references)++] = conn;
} }
mg_unlock_context(conn->ctx); mg_unlock_context(conn->ctx);
printf("XXXXX ws == %p)\n", ws); printf("%p XXXXX ws == %p)\n", pthread_self(), ws);
/* call add */ /* call add */
lua_getglobal(ws->state, "open"); lua_getglobal(ws->state, "open");
@@ -1561,7 +1561,7 @@ printf("XXXXX ws == %p)\n", ws);
lua_pushlightuserdata(ws->state, (void *)conn); lua_pushlightuserdata(ws->state, (void *)conn);
lua_rawset(ws->state, -3); 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); err = lua_pcall(ws->state, 1, 1, 0);
if (err != 0) { if (err != 0) {
@@ -1579,9 +1579,9 @@ printf("XXXXX lua_pcall == %p)\n", ws->state);
(*shared_websock_list)->ws.conn[--(ws->references)] = 0; (*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)); (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; return ok ? (void *)ws : NULL;
} }
@@ -1599,9 +1599,9 @@ lua_websocket_data(struct mg_connection *conn,
assert(ws != NULL); assert(ws != NULL);
assert(ws->state != 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)); (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_getglobal(ws->state, "data");
lua_newtable(ws->state); lua_newtable(ws->state);
@@ -1627,9 +1627,9 @@ printf("ddddd locked == %p)\n", ws);
} }
lua_pop(ws->state, 1); 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)); (void)pthread_mutex_unlock(&(ws->ws_mutex));
printf("ddddd unlocked == %p)\n", ws); printf("%p ddddd unlocked == %p)\n", pthread_self(), ws);
return ok; return ok;
} }
@@ -1643,29 +1643,35 @@ lua_websocket_ready(struct mg_connection *conn, void *ws_arg)
assert(ws != NULL); assert(ws != NULL);
assert(ws->state != 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)); (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_getglobal(ws->state, "ready");
lua_newtable(ws->state); lua_newtable(ws->state);
lua_pushstring(ws->state, "client"); lua_pushstring(ws->state, "client");
lua_pushlightuserdata(ws->state, (void *)conn); lua_pushlightuserdata(ws->state, (void *)conn);
lua_rawset(ws->state, -3); lua_rawset(ws->state, -3);
printf("r2\n");
err = lua_pcall(ws->state, 1, 1, 0); err = lua_pcall(ws->state, 1, 1, 0);
printf("r3\n");
if (err != 0) { if (err != 0) {
printf("r4\n");
lua_cry(conn, err, ws->state, ws->script, "ready handler"); lua_cry(conn, err, ws->state, ws->script, "ready handler");
printf("r5\n");
} else { } else {
printf("r6\n");
if (lua_isboolean(ws->state, -1)) { if (lua_isboolean(ws->state, -1)) {
ok = lua_toboolean(ws->state, -1); ok = lua_toboolean(ws->state, -1);
} }
printf("r7\n");
lua_pop(ws->state, 1); 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)); (void)pthread_mutex_unlock(&(ws->ws_mutex));
printf("rrrrr unlocked == %p)\n", ws); printf("%p rrrrr unlocked == %p)\n", pthread_self(), ws);
return ok; return ok;
} }
@@ -1682,9 +1688,9 @@ lua_websocket_close(struct mg_connection *conn, void *ws_arg)
assert(ws != NULL); assert(ws != NULL);
assert(ws->state != 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)); (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_getglobal(ws->state, "close");
lua_newtable(ws->state); lua_newtable(ws->state);
@@ -1707,8 +1713,8 @@ printf("ccccc locked == %p)\n", ws);
asynchronous operations and timers are completed/expired. */ asynchronous operations and timers are completed/expired. */
(void)shared_websock_list; /* shared_websock_list unused (see open TODO) */ (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)); (void)pthread_mutex_unlock(&(ws->ws_mutex));
printf("ccccc unlocked == %p)\n", ws); printf("%p ccccc unlocked == %p)\n", pthread_self(), ws);
} }
#endif #endif