Skip to content

Commit

Permalink
Better bubble errors to async/await operations
Browse files Browse the repository at this point in the history
  • Loading branch information
lpereira committed May 18, 2024
1 parent bcf9dbc commit 3356985
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 42 deletions.
23 changes: 14 additions & 9 deletions src/lib/lwan-request.c
Original file line number Diff line number Diff line change
Expand Up @@ -2086,11 +2086,13 @@ ssize_t lwan_request_async_read_flags(
if (r < 0) {
switch (errno) {
case EWOULDBLOCK:
lwan_request_await_read(request, fd);
r = lwan_request_await_read(request, fd);
if (UNLIKELY(r < 0))
return (int)r;
/* Fallthrough */
case EINTR:
continue;
case EPIPE:
default:
return -errno;
}
}
Expand Down Expand Up @@ -2118,11 +2120,13 @@ ssize_t lwan_request_async_write(struct lwan_request *request,
if (r < 0) {
switch (errno) {
case EWOULDBLOCK:
lwan_request_await_write(request, fd);
r = lwan_request_await_write(request, fd);
if (UNLIKELY(r < 0))
return (int)r;
/* Fallthrough */
case EINTR:
continue;
case EPIPE:
default:
return -errno;
}
}
Expand All @@ -2142,6 +2146,7 @@ ssize_t lwan_request_async_writev(struct lwan_request *request,
for (int tries = 10; tries;) {
const int remaining_len = (int)(iov_count - curr_iov);
ssize_t written;
int r;

if (remaining_len == 1) {
const struct iovec *vec = &iov[curr_iov];
Expand All @@ -2159,7 +2164,7 @@ ssize_t lwan_request_async_writev(struct lwan_request *request,
case EINTR:
goto try_again;
default:
goto out;
return -errno;
}
}

Expand All @@ -2178,12 +2183,12 @@ ssize_t lwan_request_async_writev(struct lwan_request *request,
iov[curr_iov].iov_len -= (size_t)written;

try_again:
lwan_request_await_write(request, fd);
r = lwan_request_await_write(request, fd);
if (UNLIKELY(r < 0))
return r;
}

out:
coro_yield(request->conn->coro, CONN_CORO_ABORT);
__builtin_unreachable();
return -ETIMEDOUT;
}

void lwan_request_foreach_header_for_cgi(struct lwan_request *request,
Expand Down
58 changes: 25 additions & 33 deletions src/lib/lwan-thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,12 +644,11 @@ static void unasync_await_conn(void *data1, void *data2)
async_fd_conn->next = -1;
}

static enum lwan_connection_coro_yield
prepare_await(const struct lwan *l,
enum lwan_connection_coro_yield yield_result,
int await_fd,
struct lwan_connection *conn,
int epoll_fd)
static int prepare_await(const struct lwan *l,
enum lwan_connection_coro_yield yield_result,
int await_fd,
struct lwan_connection *conn,
int epoll_fd)
{
static const enum lwan_connection_flags to_connection_flags[] = {
[CONN_CORO_WANT_READ] = CONN_EVENTS_READ,
Expand All @@ -668,7 +667,7 @@ prepare_await(const struct lwan *l,
struct lwan_connection *await_fd_conn = &l->conns[await_fd];
if (LIKELY(await_fd_conn->flags & CONN_ASYNC_AWAIT)) {
if (LIKELY((await_fd_conn->flags & CONN_EVENTS_MASK) == flags))
return CONN_CORO_SUSPEND;
return 0;

op = EPOLL_CTL_MOD;
} else {
Expand Down Expand Up @@ -700,10 +699,10 @@ prepare_await(const struct lwan *l,
if (LIKELY(!epoll_ctl(epoll_fd, op, await_fd, &event))) {
await_fd_conn->flags &= ~CONN_EVENTS_MASK;
await_fd_conn->flags |= flags;
return CONN_CORO_SUSPEND;
return 0;
}

return CONN_CORO_ABORT;
return -errno;
}

static void clear_awaitv_flags(struct lwan_connection *conns, va_list ap_orig)
Expand Down Expand Up @@ -760,10 +759,12 @@ static int prepare_awaitv(struct lwan_request *r,
state->request_conn_yield = events;
continue;
}
if (UNLIKELY(prepare_await(l, events, await_fd, r->conn, epoll_fd) ==
CONN_CORO_ABORT)) {
lwan_status_error("could not register fd for async operation");
return -EIO;

int ret = prepare_await(l, events, await_fd, r->conn, epoll_fd);
if (UNLIKELY(ret < 0)) {
errno = -ret;
lwan_status_perror("prepare_await(%d)", await_fd);
return ret;
}
}

Expand Down Expand Up @@ -814,12 +815,8 @@ int lwan_request_awaitv_all(struct lwan_request *r, ...)
int ret = prepare_awaitv(r, l, ap, &state);
va_end(ap);

if (UNLIKELY(ret < 0)) {
errno = -ret;
lwan_status_perror("prepare_awaitv()");
coro_yield(r->conn->coro, CONN_CORO_ABORT);
__builtin_unreachable();
}
if (UNLIKELY(ret < 0))
return ret;

for (ret = 0; state.num_awaiting;) {
int64_t v = coro_yield(r->conn->coro, state.request_conn_yield);
Expand All @@ -842,7 +839,7 @@ int lwan_request_awaitv_all(struct lwan_request *r, ...)
}
}

return -1;
return -EISCONN;
}

static inline int async_await_fd(struct lwan_connection *conn,
Expand All @@ -851,21 +848,16 @@ static inline int async_await_fd(struct lwan_connection *conn,
{
struct lwan_thread *thread = conn->thread;
struct lwan *lwan = thread->lwan;
enum lwan_connection_coro_yield yield =
prepare_await(lwan, events, fd, conn, thread->epoll_fd);

if (LIKELY(yield == CONN_CORO_SUSPEND)) {
int64_t v = coro_yield(conn->coro, yield);
int r = prepare_await(lwan, events, fd, conn, thread->epoll_fd);

fd =
lwan_connection_get_fd(lwan, (struct lwan_connection *)(intptr_t)v);
if (UNLIKELY(r < 0))
return r;

return UNLIKELY(conn->flags & CONN_HUNG_UP) ? -fd : fd;
}

lwan_status_perror("prepare_await(%d)", fd);
coro_yield(conn->coro, CONN_CORO_ABORT);
__builtin_unreachable();
conn = (struct lwan_connection *)(intptr_t)coro_yield(conn->coro,
CONN_CORO_SUSPEND);
return UNLIKELY(conn->flags & CONN_HUNG_UP)
? -ECONNRESET
: lwan_connection_get_fd(lwan, conn);
}

int lwan_request_await_read(struct lwan_request *r, int fd)
Expand Down

0 comments on commit 3356985

Please sign in to comment.