diff --git a/include/types/hlua.h b/include/types/hlua.h index 74dcf0040..e8daf53fe 100644 --- a/include/types/hlua.h +++ b/include/types/hlua.h @@ -156,6 +156,7 @@ struct hlua_sleep { struct hlua_socket { struct xref xref; /* cross reference with the stream used for socket I/O. */ luaL_Buffer b; /* buffer used to prepare strings. */ + unsigned long tid; /* Store the thread id which creates the socket. */ }; struct hlua_concat { diff --git a/src/hlua.c b/src/hlua.c index 3bb46bb04..1d14e5486 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -1630,6 +1630,13 @@ __LJMP static int hlua_socket_close(lua_State *L) MAY_LJMP(check_args(L, 1, "close")); socket = MAY_LJMP(hlua_checksocket(L, 1)); + + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + peer = xref_get_peer(&socket->xref); if (!peer) { xref_disconnect(&socket->xref); @@ -1680,6 +1687,12 @@ __LJMP static int hlua_socket_receive_yield(struct lua_State *L, int status, lua WILL_LJMP(luaL_error(L, "The 'receive' function is only allowed in " "'frontend', 'backend' or 'task'")); + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + /* check for connection break. If some data where read, return it. */ peer = xref_get_peer(&socket->xref); if (!peer) { @@ -1822,6 +1835,12 @@ __LJMP static int hlua_socket_receive(struct lua_State *L) socket = MAY_LJMP(hlua_checksocket(L, 1)); + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + /* check for pattern. */ if (lua_gettop(L) >= 2) { type = lua_type(L, 2); @@ -1889,6 +1908,12 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len)); sent = MAY_LJMP(luaL_checkinteger(L, 3)); + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + /* check for connection break. If some data where read, return it. */ peer = xref_get_peer(&socket->xref); if (!peer) { @@ -2111,6 +2136,12 @@ __LJMP static int hlua_socket_getpeername(struct lua_State *L) socket = MAY_LJMP(hlua_checksocket(L, 1)); + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + /* check for connection break. If some data where read, return it. */ peer = xref_get_peer(&socket->xref); if (!peer) { @@ -2151,6 +2182,12 @@ static int hlua_socket_getsockname(struct lua_State *L) socket = MAY_LJMP(hlua_checksocket(L, 1)); + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + /* check for connection break. If some data where read, return it. */ peer = xref_get_peer(&socket->xref); if (!peer) { @@ -2194,6 +2231,12 @@ __LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua struct stream_interface *si; struct stream *s; + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + /* check for connection break. If some data where read, return it. */ peer = xref_get_peer(&socket->xref); if (!peer) { @@ -2206,6 +2249,12 @@ __LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua si = appctx->owner; s = si_strm(si); + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + /* Check for connection close. */ if (!hlua || channel_output_closed(&s->req)) { lua_pushnil(L); @@ -2247,6 +2296,13 @@ __LJMP static int hlua_socket_connect(struct lua_State *L) /* Get args. */ socket = MAY_LJMP(hlua_checksocket(L, 1)); + + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + ip = MAY_LJMP(luaL_checkstring(L, 2)); if (lua_gettop(L) >= 3) port = MAY_LJMP(luaL_checkinteger(L, 3)); @@ -2357,6 +2413,12 @@ __LJMP static int hlua_socket_settimeout(struct lua_State *L) socket = MAY_LJMP(hlua_checksocket(L, 1)); tmout = MAY_LJMP(luaL_checkinteger(L, 2)) * 1000; + /* Check if we run on the same thread than the xreator thread. + * We cannot access to the socket if the thread is different. + */ + if (socket->tid != tid) + WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread")); + /* check for connection break. If some data where read, return it. */ peer = xref_get_peer(&socket->xref); if (!peer) { @@ -2395,6 +2457,7 @@ __LJMP static int hlua_socket_new(lua_State *L) socket = MAY_LJMP(lua_newuserdata(L, sizeof(*socket))); lua_rawseti(L, -2, 0); memset(socket, 0, sizeof(*socket)); + socket->tid = tid; /* Check if the various memory pools are intialized. */ if (!pool2_stream || !pool2_buffer) {