MINOR: hlua: add an optional timeout to AppletTCP:receive()
TCP services might want to be interactive, and without a timeout on receive(), the possibilities are a bit limited. Let's add an optional timeout in the 3rd argument to possibly limit the wait time. In this case if the timeout strikes before the requested size is complete, a possibly incomplete block will be returned.
This commit is contained in:
parent
557f62593f
commit
19e48f237f
@ -3886,11 +3886,13 @@ AppletTCP class
|
|||||||
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
||||||
:returns: a string. The string can be empty if we reach the end of the stream.
|
:returns: a string. The string can be empty if we reach the end of the stream.
|
||||||
|
|
||||||
.. js:function:: AppletTCP.receive(applet, [size])
|
.. js:function:: AppletTCP.receive(applet, [size, [timeout]])
|
||||||
|
|
||||||
Reads data from the TCP stream, according to the specified read *size*. If the
|
Reads data from the TCP stream, according to the specified read *size*. If the
|
||||||
*size* is missing, the function tries to read all the content of the stream
|
*size* is missing, the function tries to read all the content of the stream
|
||||||
until the end.
|
until the end. An optional timeout may be specified in milliseconds. In this
|
||||||
|
case the function will return no longer than this delay, with the amount of
|
||||||
|
available data (possibly none).
|
||||||
|
|
||||||
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
||||||
:param integer size: the required read size.
|
:param integer size: the required read size.
|
||||||
|
36
src/hlua.c
36
src/hlua.c
@ -5321,6 +5321,7 @@ __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KCont
|
|||||||
struct hlua_appctx *luactx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
|
struct hlua_appctx *luactx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
|
||||||
struct stconn *sc = appctx_sc(luactx->appctx);
|
struct stconn *sc = appctx_sc(luactx->appctx);
|
||||||
size_t len = MAY_LJMP(luaL_checkinteger(L, 2));
|
size_t len = MAY_LJMP(luaL_checkinteger(L, 2));
|
||||||
|
int exp_date = MAY_LJMP(luaL_checkinteger(L, -1));
|
||||||
int ret;
|
int ret;
|
||||||
const char *blk1;
|
const char *blk1;
|
||||||
size_t len1;
|
size_t len1;
|
||||||
@ -5335,8 +5336,14 @@ __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KCont
|
|||||||
|
|
||||||
/* Data not yet available. return yield. */
|
/* Data not yet available. return yield. */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
if (tick_is_expired(exp_date, now_ms)) {
|
||||||
|
/* return the result. */
|
||||||
|
luaL_pushresult(&luactx->b);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
applet_need_more_data(luactx->appctx);
|
applet_need_more_data(luactx->appctx);
|
||||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0));
|
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, exp_date, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of data: commit the total strings and return. */
|
/* End of data: commit the total strings and return. */
|
||||||
@ -5361,8 +5368,15 @@ __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KCont
|
|||||||
b_del(&luactx->appctx->inbuf, len1 + len2);
|
b_del(&luactx->appctx->inbuf, len1 + len2);
|
||||||
else
|
else
|
||||||
co_skip(sc_oc(sc), len1 + len2);
|
co_skip(sc_oc(sc), len1 + len2);
|
||||||
|
|
||||||
|
if (tick_is_expired(exp_date, now_ms)) {
|
||||||
|
/* return the result. */
|
||||||
|
luaL_pushresult(&luactx->b);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
applet_need_more_data(luactx->appctx);
|
applet_need_more_data(luactx->appctx);
|
||||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0));
|
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, exp_date, 0));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -5384,11 +5398,11 @@ __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KCont
|
|||||||
co_skip(sc_oc(sc), len1 + len2);
|
co_skip(sc_oc(sc), len1 + len2);
|
||||||
|
|
||||||
/* If there is no other data available, yield waiting for new data. */
|
/* If there is no other data available, yield waiting for new data. */
|
||||||
if (len > 0) {
|
if (len > 0 && !tick_is_expired(exp_date, now_ms)) {
|
||||||
lua_pushinteger(L, len);
|
lua_pushinteger(L, len);
|
||||||
lua_replace(L, 2);
|
lua_replace(L, 2);
|
||||||
applet_need_more_data(luactx->appctx);
|
applet_need_more_data(luactx->appctx);
|
||||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0));
|
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, exp_date, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the result. */
|
/* return the result. */
|
||||||
@ -5406,11 +5420,17 @@ __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KCont
|
|||||||
__LJMP static int hlua_applet_tcp_recv(lua_State *L)
|
__LJMP static int hlua_applet_tcp_recv(lua_State *L)
|
||||||
{
|
{
|
||||||
struct hlua_appctx *luactx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
|
struct hlua_appctx *luactx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
|
||||||
|
int exp_date;
|
||||||
|
int delay = 0;
|
||||||
int len = -1;
|
int len = -1;
|
||||||
|
|
||||||
if (lua_gettop(L) > 2)
|
if (lua_gettop(L) > 3)
|
||||||
WILL_LJMP(luaL_error(L, "The 'recv' function requires between 1 and 2 arguments."));
|
WILL_LJMP(luaL_error(L, "The 'recv' function requires between 1 and 3 arguments."));
|
||||||
if (lua_gettop(L) >= 2) {
|
if (lua_gettop(L) >= 2) {
|
||||||
|
if (lua_gettop(L) >= 3) {
|
||||||
|
delay = MAY_LJMP(luaL_checkinteger(L, 3));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
len = MAY_LJMP(luaL_checkinteger(L, 2));
|
len = MAY_LJMP(luaL_checkinteger(L, 2));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
@ -5418,6 +5438,10 @@ __LJMP static int hlua_applet_tcp_recv(lua_State *L)
|
|||||||
/* Confirm or set the required length */
|
/* Confirm or set the required length */
|
||||||
lua_pushinteger(L, len);
|
lua_pushinteger(L, len);
|
||||||
|
|
||||||
|
/* set the expiration date */
|
||||||
|
exp_date = delay ? tick_add(now_ms, delay) : TICK_ETERNITY;
|
||||||
|
lua_pushinteger(L, exp_date);
|
||||||
|
|
||||||
/* Initialise the string catenation. */
|
/* Initialise the string catenation. */
|
||||||
luaL_buffinit(L, &luactx->b);
|
luaL_buffinit(L, &luactx->b);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user