]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: threads/lua: Cannot acces to the socket if we try to access from another...
authorThierry FOURNIER <thierry.fournier@ozon.io>
Wed, 12 Jul 2017 10:10:44 +0000 (12:10 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 31 Oct 2017 12:58:32 +0000 (13:58 +0100)
We have two y for nsuring that the data is not concurently manipulated:
 - locks
 - running task on the same thread.
locks are expensives, it is better to avoid it.

This patch cecks that the Lua task run on the same thread that
the stream associated to the coprocess.

TODO: in a next version, the error should be replaced by a yield
and thread migration request.

include/types/hlua.h
src/hlua.c

index 74dcf0040bccbc34589c7685631acb404476f79e..e8daf53fe4d1a07441e2cc0b5b7022af7e2f76dc 100644 (file)
@@ -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 {
index 3bb46bb049e82114678a84f7ae50584f939bd1ba..1d14e54863ea91e5142f3ad2b6b52e35cb97da9b 100644 (file)
@@ -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) {