From 534f78acb3c83d4f2b077b51cfffb3c12725f8dc Mon Sep 17 00:00:00 2001 From: Unbit Date: Wed, 30 Jan 2013 12:51:13 +0100 Subject: [PATCH] improved sendfile management --- core/logging.c | 2 +- core/static.c | 12 +++--------- core/writer.c | 16 ++++++++++++++-- plugins/psgi/psgi_response.c | 1 + plugins/python/uwsgi_pymodule.c | 21 ++------------------- plugins/rack/rack_plugin.c | 1 - welcome.py | 2 +- 7 files changed, 22 insertions(+), 33 deletions(-) diff --git a/core/logging.c b/core/logging.c index 909c1c70..4f333071 100644 --- a/core/logging.c +++ b/core/logging.c @@ -556,7 +556,7 @@ void log_request(struct wsgi_request *wsgi_req) { if (uwsgi.shared->options[UWSGI_OPTION_LOG_BIG] && (wsgi_req->response_size >= uwsgi.shared->options[UWSGI_OPTION_LOG_BIG])) { goto logit; } - if (uwsgi.shared->options[UWSGI_OPTION_LOG_SENDFILE] && (wsgi_req->sendfile_fd > -1 && wsgi_req->sendfile_obj == wsgi_req->async_result)) { + if (uwsgi.shared->options[UWSGI_OPTION_LOG_SENDFILE] && wsgi_req->via == UWSGI_VIA_SENDFILE) { goto logit; } diff --git a/core/static.c b/core/static.c index 01226ef0..6d0ba80d 100644 --- a/core/static.c +++ b/core/static.c @@ -441,17 +441,11 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si } // Ok, the file must be transferred from uWSGI - if (wsgi_req->socket->can_offload) { - if (!uwsgi_offload_request_sendfile_do(wsgi_req, real_filename, -1, st->st_size)) { - wsgi_req->via = UWSGI_VIA_OFFLOAD; - wsgi_req->response_size += st->st_size; - return 0; - } - } - + // offloading will be automatically managed int fd = open(real_filename, O_RDONLY); + if (fd < 0) return -1; + // fd will be closed in the following function uwsgi_response_sendfile_do(wsgi_req, fd, 0, st->st_size); - close(fd); } wsgi_req->status = 200; diff --git a/core/writer.c b/core/writer.c index 5350bd94..14a8d569 100644 --- a/core/writer.c +++ b/core/writer.c @@ -181,6 +181,10 @@ sendbody: int uwsgi_response_sendfile_do(struct wsgi_request *wsgi_req, int fd, size_t pos, size_t len) { + int can_close = 1; + + if (fd == wsgi_req->sendfile_fd) can_close = 0; + if (wsgi_req->write_errors) return -1; if (!wsgi_req->headers_sent) { @@ -188,6 +192,7 @@ int uwsgi_response_sendfile_do(struct wsgi_request *wsgi_req, int fd, size_t pos if (ret == UWSGI_OK) goto sendfile; if (ret == UWSGI_AGAIN) return UWSGI_AGAIN; wsgi_req->write_errors++; + if (can_close) close(fd); return -1; } @@ -198,6 +203,7 @@ sendfile: if (fstat(fd, &st)) { uwsgi_error("fstat()"); wsgi_req->write_errors++; + if (can_close) close(fd); return -1; } len = st.st_size; @@ -221,13 +227,18 @@ sendfile: uwsgi_error("uwsgi_response_sendfile_do()"); } wsgi_req->write_errors++; + if (can_close) close(fd); return -1; } if (ret == UWSGI_OK) { break; } ret = uwsgi.wait_write_hook(wsgi_req); - if (ret < 0) { wsgi_req->write_errors++; return -1;} + if (ret < 0) { + wsgi_req->write_errors++; + if (can_close) close(fd); + return -1; + } // callback based hook... if (ret == UWSGI_AGAIN) return UWSGI_AGAIN; } @@ -235,7 +246,8 @@ sendfile: wsgi_req->response_size += wsgi_req->write_pos; // reset for the next write wsgi_req->write_pos = 0; - + // close the file descriptor + if (can_close) close(fd); return UWSGI_OK; } diff --git a/plugins/psgi/psgi_response.c b/plugins/psgi/psgi_response.c index 4c91bf66..5aff365f 100644 --- a/plugins/psgi/psgi_response.c +++ b/plugins/psgi/psgi_response.c @@ -112,6 +112,7 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) { uwsgi_pl_check_write_errors { // noop } + close(wsgi_req->sendfile_fd); return UWSGI_OK; } SvREFCNT_dec(fn); diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index e083e3d9..fe116e2c 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -878,28 +878,11 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) { } } - int tmp_fd = wsgi_req->sendfile_fd; - size_t tmp_filesize = wsgi_req->sendfile_fd_size; - size_t tmp_chunk = wsgi_req->sendfile_fd_chunk; - off_t tmp_pos = wsgi_req->sendfile_fd_pos; - - wsgi_req->sendfile_fd = fd; - wsgi_req->sendfile_fd_size = filesize; - wsgi_req->sendfile_fd_chunk = chunk; - wsgi_req->sendfile_fd_pos = pos; - UWSGI_RELEASE_GIL - uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, wsgi_req->sendfile_fd_pos, wsgi_req->sendfile_fd_size); + // fd is closed by the following function + uwsgi_response_sendfile_do(wsgi_req, fd, pos, filesize); UWSGI_GET_GIL // revert to old values - wsgi_req->sendfile_fd = tmp_fd; - wsgi_req->sendfile_fd_size = tmp_filesize; - wsgi_req->sendfile_fd_chunk = tmp_chunk; - wsgi_req->sendfile_fd_pos = tmp_pos; - - - close(fd); - uwsgi_py_check_write_errors { uwsgi_py_write_exception(wsgi_req); return NULL; diff --git a/plugins/rack/rack_plugin.c b/plugins/rack/rack_plugin.c index a8ab102d..76fcd1a4 100644 --- a/plugins/rack/rack_plugin.c +++ b/plugins/rack/rack_plugin.c @@ -870,7 +870,6 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) { else { wsgi_req->sendfile_fd = open(RSTRING_PTR(sendfile_path), O_RDONLY); uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, 0, 0); - // we need to close it... close(wsgi_req->sendfile_fd); } } diff --git a/welcome.py b/welcome.py index 79e675d7..dc898292 100644 --- a/welcome.py +++ b/welcome.py @@ -42,7 +42,7 @@ def xsendfile(e, sr): return '' def serve_logo(e, sr): - # use raw facilities + # use raw facilities (status will not be set...) uwsgi.send("%s 200 OK\r\nContent-Type: image/png\r\n\r\n" % e['SERVER_PROTOCOL']) uwsgi.sendfile('logo_uWSGI.png') return ''