From 4e2178ffab171724ab02b24dfff42e3cf2b3426b Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Sun, 20 Jan 2013 11:41:43 +0100 Subject: [PATCH] another WSGI optimization --- core/sendfile.c | 27 ++------------------- core/writer.c | 12 +++++++-- plugins/python/pyloader.c | 2 ++ plugins/python/wsgi_subhandler.c | 4 +-- plugins/router_basicauth/router_basicauth.c | 2 ++ proto/base.c | 10 ++++++++ proto/fastcgi.c | 2 +- proto/uwsgi.c | 1 + 8 files changed, 29 insertions(+), 31 deletions(-) diff --git a/core/sendfile.c b/core/sendfile.c index 788eef9a..b5e467ba 100644 --- a/core/sendfile.c +++ b/core/sendfile.c @@ -38,31 +38,8 @@ ssize_t uwsgi_sendfile_do(int sockfd, int filefd, size_t pos, size_t len) { return -1; #elif defined(__linux__) || defined(__sun__) - int sf_ret; - size_t written = 0; - - if (async > 1) { - sf_ret = sendfile(sockfd, filefd, pos, chunk); - if (sf_ret < 0) { - uwsgi_error("sendfile()"); - return 0; - } - return sf_ret; - } - - while (written < filesize) { - sf_ret = sendfile(sockfd, filefd, pos, filesize - written); - if (sf_ret < 0) { - uwsgi_error("sendfile()"); - return 0; - } - else if (sf_ret == 0) { - return 0; - } - written += sf_ret; - } - return written; - + off_t off = pos; + return sendfile(sockfd, filefd, &off, len); #else static size_t nosf_buf_size = 0; static char *nosf_buf; diff --git a/core/writer.c b/core/writer.c index 35b52f05..db384876 100644 --- a/core/writer.c +++ b/core/writer.c @@ -5,7 +5,7 @@ extern struct uwsgi_server uwsgi; // status could be NNN or NNN message int uwsgi_response_prepare_headers(struct wsgi_request *wsgi_req, char *status, uint16_t status_len) { - if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size) return -1; + if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size || status_len < 3) return -1; if (!wsgi_req->headers) { wsgi_req->headers = uwsgi_buffer_new(uwsgi.page_size); @@ -18,6 +18,7 @@ int uwsgi_response_prepare_headers(struct wsgi_request *wsgi_req, char *status, if (!hh) return -1; if (uwsgi_buffer_append(wsgi_req->headers, hh->buf, hh->pos)) goto error; uwsgi_buffer_destroy(hh); + wsgi_req->status = uwsgi_str3_num(status); return 0; error: uwsgi_buffer_destroy(hh); @@ -79,9 +80,16 @@ int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) { int uwsgi_response_write_body_do(struct wsgi_request *wsgi_req, char *buf, size_t len) { if (!wsgi_req->headers_sent) { - return uwsgi_response_write_headers_do(wsgi_req); + int ret = uwsgi_response_write_headers_do(wsgi_req); + if (ret == UWSGI_OK) goto sendbody; + if (ret == UWSGI_AGAIN) return UWSGI_AGAIN; + return -1; } +sendbody: + + if (len == 0) return UWSGI_OK; + for(;;) { int ret = wsgi_req->socket->proto_write(wsgi_req, buf, len); if (ret < 0) { diff --git a/plugins/python/pyloader.c b/plugins/python/pyloader.c index c568419e..9417c71b 100644 --- a/plugins/python/pyloader.c +++ b/plugins/python/pyloader.c @@ -339,6 +339,8 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre } // cache most used values + wi->error = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL); + Py_INCREF(wi->error); wi->gateway_version = PyTuple_New(2); PyTuple_SetItem(wi->gateway_version, 0, PyInt_FromLong(1)); diff --git a/plugins/python/wsgi_subhandler.c b/plugins/python/wsgi_subhandler.c index 3fc1ae15..123c5f64 100644 --- a/plugins/python/wsgi_subhandler.c +++ b/plugins/python/wsgi_subhandler.c @@ -82,9 +82,7 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ PyDict_SetItemString(wsgi_req->async_environ, "wsgi.version", wi->gateway_version); - zero = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL); - PyDict_SetItemString(wsgi_req->async_environ, "wsgi.errors", zero); - Py_DECREF(zero); + PyDict_SetItemString(wsgi_req->async_environ, "wsgi.errors", wi->error); PyDict_SetItemString(wsgi_req->async_environ, "wsgi.run_once", Py_False); diff --git a/plugins/router_basicauth/router_basicauth.c b/plugins/router_basicauth/router_basicauth.c index 77d607fa..57bb99aa 100644 --- a/plugins/router_basicauth/router_basicauth.c +++ b/plugins/router_basicauth/router_basicauth.c @@ -61,6 +61,7 @@ static uint16_t htpasswd_check(char *filename, char *auth) { int uwsgi_routing_func_basicauth(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { +/* struct iovec iov[4]; if (wsgi_req->protocol_len > 0) { @@ -71,6 +72,7 @@ int uwsgi_routing_func_basicauth(struct wsgi_request *wsgi_req, struct uwsgi_rou iov[0].iov_base = "HTTP/1.0"; iov[0].iov_len = 8; } +*/ // check for "Basic =" string at least if (wsgi_req->authorization_len > 7 && ur->data2_len > 0) { diff --git a/proto/base.c b/proto/base.c index 759470d6..e830a5d6 100644 --- a/proto/base.c +++ b/proto/base.c @@ -91,7 +91,17 @@ uint16_t proto_base_add_uwsgi_var(struct wsgi_request * wsgi_req, char *key, uin int uwsgi_proto_base_accept(struct wsgi_request *wsgi_req, int fd) { wsgi_req->c_len = sizeof(struct sockaddr_un); +#if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL) + return accept4(fd, (struct sockaddr *) &wsgi_req->c_addr, (socklen_t *) & wsgi_req->c_len, SOCK_NONBLOCK); +#elif defined(__linux__) + int client_fd = accept(fd, (struct sockaddr *) &wsgi_req->c_addr, (socklen_t *) & wsgi_req->c_len); + if (client_fd >= 0) { + uwsgi_socket_nb(client_fd); + } + return client_fd; +#else return accept(fd, (struct sockaddr *) &wsgi_req->c_addr, (socklen_t *) & wsgi_req->c_len); +#endif } void uwsgi_proto_base_close(struct wsgi_request *wsgi_req) { diff --git a/proto/fastcgi.c b/proto/fastcgi.c index ce273923..fc282271 100644 --- a/proto/fastcgi.c +++ b/proto/fastcgi.c @@ -171,6 +171,7 @@ ssize_t uwsgi_proto_fastcgi_writev(struct wsgi_request * wsgi_req, struct iovec } int uwsgi_proto_fastcgi_write(struct wsgi_request * wsgi_req, char *buf, size_t len) { +/* struct fcgi_record fr; // in fastcgi we need to not send 0 sized frames @@ -185,7 +186,6 @@ int uwsgi_proto_fastcgi_write(struct wsgi_request * wsgi_req, char *buf, size_t fr.reserved = 0; fr.cl = htons(len); -/* // still trying to send the fcgi header ? if (*written < 8) { char *ptr = (char *) &fr; diff --git a/proto/uwsgi.c b/proto/uwsgi.c index b2342b4e..e089fabe 100644 --- a/proto/uwsgi.c +++ b/proto/uwsgi.c @@ -140,6 +140,7 @@ int uwsgi_proto_uwsgi_sendfile(struct wsgi_request * wsgi_req, int fd, size_t po wsgi_req->write_pos += wlen; uwsgi_log("write_pos %d %d\n", wsgi_req->write_pos, len); if (wsgi_req->write_pos == len) { + uwsgi_log("OK\n"); return UWSGI_OK; } return UWSGI_AGAIN;