MEDIUM: threads/lua: Cannot acces to the socket if we try to access from another thread.

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.
diff --git a/include/types/hlua.h b/include/types/hlua.h
index 74dcf00..e8daf53 100644
--- a/include/types/hlua.h
+++ b/include/types/hlua.h
@@ -156,6 +156,7 @@
 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 3bb46bb..1d14e54 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -1630,6 +1630,13 @@
 	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 @@
 		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 @@
 
 	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 @@
 	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 @@
 
 	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 @@
 
 	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 @@
 	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 @@
 	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 @@
 
 	/* 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 @@
 	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 @@
 	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) {