mirror of
https://github.com/h2o/h2o.git
synced 2025-05-15 02:02:57 +08:00
in other parts of code, we do not abort when running out of fds, so do the same
This commit is contained in:
parent
669dd263f3
commit
afcdeb5bcc
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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)
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user