BUG/MINOR: lua: Yield in channel functions only if lua context can yield

When a script is executed, it is not always allowed to yield. Lua sample
fetches and converters cannot yield. For lua actions, it depends on the
context. When called from tcp content ruleset, an action may yield until the
expiration of the inspect-delay timeout. From http rulesets, yield is not
possible.

Thus, when channel functions (dup, get, append, send...) are called, instead
of yielding when it is not allowed and triggering an error, we just give
up. In this case, some functions do nothing (dup, append...), some others
just interrupt the in-progress job (send, forward...). But, because these
functions don't yield anymore when it is not allowed, the script regains the
control and can continue its execution.

This patch depends on "MINOR: lua: Add a flag on lua context to know the
yield capability at run time". Both may be backported in all stable
versions. However, because nobody notice this bug till now, it is probably
not necessary, excepted if someone ask for it.
diff --git a/src/hlua.c b/src/hlua.c
index b04c67a..964c617 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -2955,12 +2955,12 @@
 	luaL_Buffer b;
 
 	ret = ci_getblk_nc(chn, &blk1, &len1, &blk2, &len2);
-	if (unlikely(ret == 0))
+	if (unlikely(ret <= 0)) {
+		if (ret < 0 || HLUA_CANT_YIELD(hlua_gethlua(L))) {
+			lua_pushnil(L);
+			return -1;
+		}
 		return 0;
-
-	if (unlikely(ret < 0)) {
-		lua_pushnil(L);
-		return -1;
 	}
 
 	luaL_buffinit(L, &b);
@@ -3061,8 +3061,13 @@
 	}
 
 	ret = ci_getline_nc(chn, &blk1, &len1, &blk2, &len2);
-	if (ret == 0)
+	if (ret == 0) {
+		if (HLUA_CANT_YIELD(hlua_gethlua(L))) {
+			_hlua_channel_dup(chn, L);
+			return 1;
+		}
 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_getline_yield, TICK_ETERNITY, 0));
+	}
 
 	if (ret == -1) {
 		lua_pushnil(L);
@@ -3123,11 +3128,11 @@
 		max = len - l;
 
 	ret = ci_putblk(chn, str + l, max);
-	if (ret == -2 || ret == -3) {
-		lua_pushinteger(L, -1);
-		return 1;
-	}
-	if (ret == -1) {
+	if (ret < 0) {
+		if (ret == -2 || ret == -3 || HLUA_CANT_YIELD(hlua_gethlua(L))) {
+			lua_pushinteger(L, -1);
+			return 1;
+		}
 		chn->flags |= CF_WAKE_WRITE;
 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
 	}
@@ -3135,16 +3140,16 @@
 	lua_pop(L, 1);
 	lua_pushinteger(L, l);
 
-	max = channel_recv_limit(chn) - b_data(&chn->buf);
-	if (max == 0 && co_data(chn) == 0) {
-		/* There are no space available, and the output buffer is empty.
-		 * in this case, we cannot add more data, so we cannot yield,
-		 * we return the amount of copied data.
+	if (l < len) {
+		/* If there are no space available, and the output buffer is
+		 * empty, we cannot add more data, so we cannot yield, we return
+		 * the amount of copied data.
 		 */
-		return 1;
-	}
-	if (l < len)
+		max = channel_recv_limit(chn) - b_data(&chn->buf);
+		if ((max == 0 && co_data(chn) == 0) || HLUA_CANT_YIELD(hlua_gethlua(L)))
+			return 1;
 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
+	}
 	return 1;
 }
 
@@ -3224,6 +3229,8 @@
 	 * the request buffer if its not required.
 	 */
 	if (chn->buf.size == 0) {
+		if (HLUA_CANT_YIELD(hlua_gethlua(L)))
+			return 1;
 		si_rx_buff_blk(chn_prod(chn));
 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
 	}
@@ -3264,15 +3271,15 @@
 	lua_pop(L, 1);
 	lua_pushinteger(L, l);
 
-	/* If there is no space available, and the output buffer is empty.
-	 * in this case, we cannot add more data, so we cannot yield,
-	 * we return the amount of copied data.
-	 */
-	max = b_room(&chn->buf);
-	if (max == 0 && co_data(chn) == 0)
-		return 1;
-
 	if (l < len) {
+		/* If there is no space available, and the output buffer is empty.
+		 * in this case, we cannot add more data, so we cannot yield,
+		 * we return the amount of copied data.
+		 */
+		max = b_room(&chn->buf);
+		if ((max == 0 && co_data(chn) == 0) || HLUA_CANT_YIELD(hlua_gethlua(L)))
+			return 1;
+
 		/* If we are waiting for space in the response buffer, we
 		 * must set the flag WAKERESWR. This flag required the task
 		 * wake up if any activity is detected on the response buffer.
@@ -3343,7 +3350,7 @@
 		/* The the input channel or the output channel are closed, we
 		 * must return the amount of data forwarded.
 		 */
-		if (channel_input_closed(chn) || channel_output_closed(chn))
+		if (channel_input_closed(chn) || channel_output_closed(chn) ||  HLUA_CANT_YIELD(hlua_gethlua(L)))
 			return 1;
 
 		/* If we are waiting for space data in the response buffer, we