summaryrefslogtreecommitdiff
path: root/src/core/ngx_connection.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2011-04-04 12:50:30 +0000
committerJonathan Kolb <jon@b0g.us>2011-04-04 12:50:30 +0000
commitf241ce02a4e7971bf509ea005b4791812d54c522 (patch)
tree995761817026a7147e180731e9ccd2293326bfbb /src/core/ngx_connection.c
parentbe28c50206ac6f3f1bbbede6a495f5d0b5abad70 (diff)
downloadnginx-0.9.tar.gz
Changes with nginx 0.9.7 04 Apr 2011v0.9.7nginx-0.9
*) Feature: now keepalive connections may be closed premature, if there are no free worker connections. Thanks to Maxim Dounin. *) Feature: the "rotate" parameter of the "image_filter" directive. Thanks to Adam Bocim. *) Bugfix: a case when a backend in "fastcgi_pass", "scgi_pass", or "uwsgi_pass" directives is given by expression and refers to a defined upstream.
Diffstat (limited to 'src/core/ngx_connection.c')
-rw-r--r--src/core/ngx_connection.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index c495edd52..9f19fcc4f 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -12,6 +12,9 @@
ngx_os_io_t ngx_io;
+static void ngx_drain_connections(void);
+
+
ngx_listening_t *
ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen)
{
@@ -719,6 +722,11 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
c = ngx_cycle->free_connections;
if (c == NULL) {
+ ngx_drain_connections();
+ c = ngx_cycle->free_connections;
+ }
+
+ if (c == NULL) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
"%ui worker_connections are not enough",
ngx_cycle->connection_n);
@@ -861,6 +869,8 @@ ngx_close_connection(ngx_connection_t *c)
#endif
+ ngx_reusable_connection(c, 0);
+
log_error = c->log_error;
ngx_free_connection(c);
@@ -900,6 +910,51 @@ ngx_close_connection(ngx_connection_t *c)
}
+void
+ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
+{
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
+ "reusable connection: %ui", reusable);
+
+ if (c->reusable) {
+ ngx_queue_remove(&c->queue);
+ }
+
+ c->reusable = reusable;
+
+ if (reusable) {
+ /* need cast as ngx_cycle is volatile */
+
+ ngx_queue_insert_head(
+ (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
+ }
+}
+
+
+static void
+ngx_drain_connections(void)
+{
+ ngx_int_t i;
+ ngx_queue_t *q;
+ ngx_connection_t *c;
+
+ for (i = 0; i < 32; i++) {
+ if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {
+ break;
+ }
+
+ q = ngx_queue_last(&ngx_cycle->reusable_connections_queue);
+ c = ngx_queue_data(q, ngx_connection_t, queue);
+
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
+ "reusing connection");
+
+ c->close = 1;
+ c->read->handler(c->read);
+ }
+}
+
+
ngx_int_t
ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
ngx_uint_t port)