diff --git a/core/socket.c b/core/socket.c index 4778a457..1296da87 100644 --- a/core/socket.c +++ b/core/socket.c @@ -1826,3 +1826,13 @@ nextsock: } + +void uwsgi_tcp_nodelay(int fd) { +#ifdef TCP_NODELAY + int flag = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int))) { + uwsgi_error("uwsgi_tcp_nodelay()/setsockopt()"); + } +#endif +} + diff --git a/core/utils.c b/core/utils.c index d55bedde..97ad6fe0 100644 --- a/core/utils.c +++ b/core/utils.c @@ -938,6 +938,20 @@ int wsgi_req_recv(int queue, struct wsgi_request *wsgi_req) { return 0; } +void uwsgi_post_accept(struct wsgi_request *wsgi_req) { + + // set close on exec (if not a new socket) + if (!wsgi_req->socket->edge_trigger && uwsgi.close_on_exec) { + if (fcntl(wsgi_req->fd, F_SETFD, FD_CLOEXEC) < 0) { + uwsgi_error("fcntl()"); + } + } + + // enable TCP_NODELAY ? + if (uwsgi.tcp_nodelay) { + uwsgi_tcp_nodelay(wsgi_req->fd); + } +} // accept a new request int wsgi_req_simple_accept(struct wsgi_request *wsgi_req, int fd) { @@ -948,12 +962,7 @@ int wsgi_req_simple_accept(struct wsgi_request *wsgi_req, int fd) { return -1; } - // set close on exec (if not a new socket) - if (!wsgi_req->socket->edge_trigger && uwsgi.close_on_exec) { - if (fcntl(wsgi_req->fd, F_SETFD, FD_CLOEXEC) < 0) { - uwsgi_error("fcntl()"); - } - } + uwsgi_post_accept(wsgi_req); return 0; } @@ -1049,13 +1058,7 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) { } if (!uwsgi_sock->edge_trigger) { - - if (uwsgi.close_on_exec) { - if (fcntl(wsgi_req->fd, F_SETFD, FD_CLOEXEC) < 0) { - uwsgi_error("fcntl()"); - } - } - + uwsgi_post_accept(wsgi_req); } return 0; diff --git a/core/uwsgi.c b/core/uwsgi.c index eb43408e..55cfbfb8 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -292,6 +292,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"no-server", no_argument, 0, "force no-server mode", uwsgi_opt_true, &uwsgi.no_server, 0}, {"command-mode", no_argument, 0, "force command mode", uwsgi_opt_true, &uwsgi.command_mode, UWSGI_OPT_IMMEDIATE}, {"no-defer-accept", no_argument, 0, "disable deferred-accept on sockets", uwsgi_opt_true, &uwsgi.no_defer_accept, 0}, + {"tcp-nodelay", no_argument, 0, "enable TCP NODELAY on each request", uwsgi_opt_true, &uwsgi.tcp_nodelay, 0}, {"so-keepalive", no_argument, 0, "enable TCP KEEPALIVEs", uwsgi_opt_true, &uwsgi.so_keepalive, 0}, {"so-send-timeout", no_argument, 0, "set SO_SNDTIMEO", uwsgi_opt_set_int, &uwsgi.so_send_timeout, 0}, {"socket-send-timeout", no_argument, 0, "set SO_SNDTIMEO", uwsgi_opt_set_int, &uwsgi.so_send_timeout, 0}, diff --git a/uwsgi.h b/uwsgi.h index 40962512..d30bdbff 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2089,6 +2089,7 @@ struct uwsgi_server { void (*gbcw_hook) (void); int close_on_exec; + int tcp_nodelay; char *loop; struct uwsgi_loop *loops; @@ -3818,6 +3819,9 @@ void uwsgi_unblock_signal(int); int uwsgi_worker_is_busy(int); +void uwsgi_post_accept(struct wsgi_request *); +void uwsgi_tcp_nodelay(int); + struct uwsgi_exception_handler_instance; struct uwsgi_exception_handler { char *name;