in other parts of code, we do not abort when running out of fds, so do the same

This commit is contained in:
Kazuho Oku 2025-04-28 12:32:22 +09:00
parent 669dd263f3
commit afcdeb5bcc
4 changed files with 25 additions and 22 deletions

View File

@ -1832,9 +1832,9 @@ static void *h2o_context_get_logger_context(h2o_context_t *ctx, h2o_logger_t *lo
*/ */
static void **h2o_context_get_storage(h2o_context_t *ctx, size_t *key, void (*dispose_cb)(void *)); static void **h2o_context_get_storage(h2o_context_t *ctx, size_t *key, void (*dispose_cb)(void *));
/** /**
* provides a new pipe that has O_NONBLOCK set, possibly reusing a cached one that is empty * provides a new pipe that has O_NONBLOCK set, possibly reusing a cached one that is empty; returns a boolean indicating success
*/ */
void h2o_context_new_pipe(h2o_context_t *ctx, int fds[2]); int h2o_context_new_pipe(h2o_context_t *ctx, int fds[2]);
/** /**
* returns a pipe to the spare pipe cache * returns a pipe to the spare pipe cache
*/ */

View File

@ -299,27 +299,24 @@ void h2o_conn_set_state(h2o_conn_t *conn, h2o_conn_state_t state)
} }
} }
void h2o_context_new_pipe(h2o_context_t *ctx, int fds[2]) int h2o_context_new_pipe(h2o_context_t *ctx, int fds[2])
{ {
if (ctx->spare_pipes.count > 0) { if (ctx->spare_pipes.count > 0) {
int *src = ctx->spare_pipes.pipes[--ctx->spare_pipes.count]; int *src = ctx->spare_pipes.pipes[--ctx->spare_pipes.count];
fds[0] = src[0]; fds[0] = src[0];
fds[1] = src[1]; fds[1] = src[1];
} else { return 1;
#ifdef __linux__
if (pipe2(fds, O_NONBLOCK | O_CLOEXEC) != 0) {
char errbuf[256];
h2o_fatal("pipe2(2) failed:%s", h2o_strerror_r(errno, errbuf, sizeof(errbuf)));
}
#else
if (cloexec_pipe(fds) != 0) {
char errbuf[256];
h2o_fatal("pipe(2) failed:%s", h2o_strerror_r(errno, errbuf, sizeof(errbuf)));
}
fcntl(fds[0], F_SETFL, O_NONBLOCK);
fcntl(fds[1], F_SETFL, O_NONBLOCK);
#endif
} }
#ifdef __linux__
return pipe2(fds, O_NONBLOCK | O_CLOEXEC) == 0;
#else
if (cloexec_pipe(fds) != 0)
return 0;
fcntl(fds[0], F_SETFL, O_NONBLOCK);
fcntl(fds[1], F_SETFL, O_NONBLOCK);
return 1;
#endif
} }
static int empty_pipe(int fd) static int empty_pipe(int fd)

View File

@ -643,9 +643,13 @@ static h2o_httpclient_body_cb on_head(h2o_httpclient_t *client, const char *errs
/* switch to using pipe reader, if the opportunity is provided */ /* switch to using pipe reader, if the opportunity is provided */
if (args->pipe_reader != NULL) { if (args->pipe_reader != NULL) {
h2o_context_new_pipe(req->conn->ctx, self->pipe_reader.fds); if (h2o_context_new_pipe(req->conn->ctx, self->pipe_reader.fds)) {
args->pipe_reader->fd = self->pipe_reader.fds[1]; args->pipe_reader->fd = self->pipe_reader.fds[1];
args->pipe_reader->on_body_piped = on_body_piped; args->pipe_reader->on_body_piped = on_body_piped;
} else {
assert(self->pipe_reader.fds[0] == -1); /* check the field remains marked as unused */
h2o_req_log_error(req, "lib/core/proxy.c", "failed to allocate zero-copy pipe; falling back to read/write");
}
} }
/* if httpclient has no received body at this time, immediately send only headers using zero timeout */ /* if httpclient has no received body at this time, immediately send only headers using zero timeout */

View File

@ -392,11 +392,13 @@ Opened:
self->send_etag = (flags & H2O_FILE_FLAG_NO_ETAG) == 0; self->send_etag = (flags & H2O_FILE_FLAG_NO_ETAG) == 0;
self->gunzip = gunzip; self->gunzip = gunzip;
#if H2O_USE_IO_URING #if H2O_USE_IO_URING
if ((flags & H2O_FILE_FLAG_IO_URING) != 0 && self->bytesleft != 0) { int try_async_splice = (flags & H2O_FILE_FLAG_IO_URING) != 0 && self->bytesleft != 0;
if (try_async_splice && h2o_context_new_pipe(req->conn->ctx, self->splice_fds)) {
self->super.stop = do_stop_async_splice; self->super.stop = do_stop_async_splice;
self->src_req = req; self->src_req = req;
h2o_context_new_pipe(req->conn->ctx, self->splice_fds);
} else { } else {
if (try_async_splice)
h2o_req_log_error(req, "lib/handler/file.c", "failed to allocate a pipe for async I/O; falling back to blocking I/O");
self->splice_fds[0] = -1; self->splice_fds[0] = -1;
self->splice_fds[1] = -1; self->splice_fds[1] = -1;
} }