Skip to content

Commit

Permalink
fix(socket): force schedule lua coroutine in send function.
Browse files Browse the repository at this point in the history
This avoids causing blocking when keep calling the send function in a loop.

Now, this code is allowed.

```
while true do
    sock:send('123')
end
```

A `sleep` operation must be inserted previously.

```
while true do
    sock:send('123')
    time.sleep(0.1)
end
```

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
  • Loading branch information
zhaojh329 committed Apr 20, 2024
1 parent dc24a0d commit 715d785
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 48 deletions.
61 changes: 27 additions & 34 deletions socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,21 +486,19 @@ static int lua_sendk(lua_State *L, int status, lua_KContext ctx)

sock->snd.co = NULL;

again:
if (sent == len) {
lua_pushinteger(L, sent);
return 1;
}

if (addrlen)
ret = sendto(sock->fd, data, len - sent, 0, (struct sockaddr *)&sock->snd.addr, addrlen);
else
ret = send(sock->fd, data, len - sent, 0);
if (ret < 0) {
if (errno == EINTR)
if (errno == EINTR || errno == EAGAIN)
goto again;

if (errno == EAGAIN) {
sock->snd.co = L;
ev_io_start(sock->eco->loop, &sock->snd.io);
return lua_yieldk(L, 0, ctx, lua_sendk);
}

lua_pushnil(L);
if (errno == EPIPE)
lua_pushliteral(L, "closed");
Expand All @@ -509,16 +507,13 @@ static int lua_sendk(lua_State *L, int status, lua_KContext ctx)
return 2;
}

sent += ret;

if (sent < len) {
sock->snd.sent = sent;
sock->snd.data += ret;
return lua_sendk(L, 0, ctx);
}
sock->snd.sent += ret;
sock->snd.data += ret;

lua_pushinteger(L, sent);
return 1;
again:
sock->snd.co = L;
ev_io_start(sock->eco->loop, &sock->snd.io);
return lua_yieldk(L, 0, ctx, lua_sendk);
}

static int lua_send(lua_State *L)
Expand Down Expand Up @@ -554,21 +549,20 @@ static int lua_sendfilek(lua_State *L, int status, lua_KContext ctx)

sock->snd.co = NULL;

again:
if (sent == len) {
close(sock->snd.fd);
lua_pushinteger(L, sent);
return 1;
}

if (offset < 0)
ret = sendfile(sock->fd, fd, NULL, len - sent);
else
ret = sendfile(sock->fd, fd, &offset, len - sent);
if (ret < 0) {
if (errno == EINTR)
if (errno == EINTR || errno == EAGAIN)
goto again;

if (errno == EAGAIN) {
sock->snd.co = L;
ev_io_start(sock->eco->loop, &sock->snd.io);
return lua_yieldk(L, 0, ctx, lua_sendfilek);
}

close(sock->snd.fd);
lua_pushnil(L);
if (errno == EPIPE)
Expand All @@ -578,17 +572,16 @@ static int lua_sendfilek(lua_State *L, int status, lua_KContext ctx)
return 2;
}

sent += ret;
sock->snd.sent += ret;
sock->snd.offset = offset;

if (ret && sent < len) {
sock->snd.sent = sent;
sock->snd.offset = offset;
return lua_sendfilek(L, 0, ctx);
}
if (ret == 0)
sock->snd.len = sock->snd.sent;

close(sock->snd.fd);
lua_pushinteger(L, sent);
return 1;
again:
sock->snd.co = L;
ev_io_start(sock->eco->loop, &sock->snd.io);
return lua_yieldk(L, 0, ctx, lua_sendfilek);
}

static int lua_sendfile(lua_State *L)
Expand Down
27 changes: 13 additions & 14 deletions ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,30 +179,29 @@ static int lua_sendk(lua_State *L, int status, lua_KContext ctx)

s->L = NULL;

if (sent == len) {
lua_pushinteger(L, sent);
return 1;
}

ret = ssl_write(s->ssl, data, len - sent);
if (unlikely(ret < 0)) {
if (ret == SSL_ERROR) {
lua_pushnil(L);
lua_pushstring(L, ssl_last_error_string(s->ssl, err_buf, sizeof(err_buf)));
return 2;
}

s->L = L;
ev_io_modify(&s->io, ret == SSL_WANT_READ ? EV_READ : EV_WRITE);
ev_io_start(s->ctx->eco->loop, &s->io);
return lua_yieldk(L, 0, ctx, lua_sendk);
goto again;
}

sent += ret;

if (sent < len) {
s->snd.sent = sent;
s->snd.data += ret;
return lua_sendk(L, 0, ctx);
}
s->snd.sent += ret;
s->snd.data += ret;

lua_pushinteger(L, sent);
return 1;
again:
s->L = L;
ev_io_modify(&s->io, ret == SSL_WANT_READ ? EV_READ : EV_WRITE);
ev_io_start(s->ctx->eco->loop, &s->io);
return lua_yieldk(L, 0, ctx, lua_sendk);
}

static int lua_send(lua_State *L)
Expand Down

0 comments on commit 715d785

Please sign in to comment.