diff src/core/ngx_connection.c @ 92:45945fa8b8ba NGINX_0_2_0

nginx 0.2.0 *) The pid-file names used during online upgrade was changed and now is not required a manual rename operation. The old master process adds the ".oldbin" suffix to its pid-file and executes a new binary file. The new master process creates usual pid-file without the ".newbin" suffix. If the master process exits, then old master process renames back its pid-file with the ".oldbin" suffix to the pid-file without suffix. *) Change: the "worker_connections" directive, new name of the "connections" directive; now the directive specifies maximum number of connections, but not maximum socket descriptor number. *) Feature: SSL supports the session cache inside one worker process. *) Feature: the "satisfy_any" directive. *) Change: the ngx_http_access_module and ngx_http_auth_basic_module do not run for subrequests. *) Feature: the "worker_rlimit_nofile" and "worker_rlimit_sigpending" directives. *) Bugfix: if all backend using in load-balancing failed after one error, then nginx did not try do connect to them during 60 seconds. *) Bugfix: in IMAP/POP3 command argument parsing. Thanks to Rob Mueller. *) Bugfix: errors while using SSL in IMAP/POP3 proxy. *) Bugfix: errors while using SSI and gzipping. *) Bugfix: the "Expires" and "Cache-Control" header lines were omitted from the 304 responses. Thanks to Alexandr Kukushkin.
author Igor Sysoev <http://sysoev.ru>
date Fri, 23 Sep 2005 00:00:00 +0400
parents 71c46860eb55
children dad2fe8ecf08
line wrap: on
line diff
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -237,13 +237,14 @@ ngx_open_listening_sockets(ngx_cycle_t *
             }
 
 #if (NGX_WIN32)
+
             /*
              * Winsock assignes a socket number divisible by 4
              * so to find a connection we divide a socket number by 4.
              */
 
             if (s % 4) {
-                ngx_log_error(NGX_LOG_EMERG, ls->log, 0,
+                ngx_log_error(NGX_LOG_EMERG, log, 0,
                               ngx_socket_n " created socket %d", s);
                 return NGX_ERROR;
             }
@@ -329,9 +330,9 @@ ngx_open_listening_sockets(ngx_cycle_t *
 void
 ngx_close_listening_sockets(ngx_cycle_t *cycle)
 {
-    ngx_uint_t        i;
-    ngx_socket_t      fd;
-    ngx_listening_t  *ls;
+    ngx_uint_t         i;
+    ngx_listening_t   *ls;
+    ngx_connection_t  *c;
 
     if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
         return;
@@ -342,35 +343,87 @@ ngx_close_listening_sockets(ngx_cycle_t 
 
     ls = cycle->listening.elts;
     for (i = 0; i < cycle->listening.nelts; i++) {
-        fd = ls[i].fd;
 
-#if (NGX_WIN32)
-        /*
-         * Winsock assignes a socket number divisible by 4
-         * so to find a connection we divide a socket number by 4.
-         */
-
-        fd /= 4;
-#endif
+        c = ls[i].connection;
 
         if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
-            if (cycle->connections[fd].read->active) {
-                ngx_del_conn(&cycle->connections[fd], NGX_CLOSE_EVENT);
+            if (c->read->active) {
+                ngx_del_conn(c, NGX_CLOSE_EVENT);
             }
 
         } else {
-            if (cycle->read_events[fd].active) {
-                ngx_del_event(&cycle->read_events[fd],
-                              NGX_READ_EVENT, NGX_CLOSE_EVENT);
+            if (c->read->active) {
+                ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
             }
         }
 
-        if (ngx_close_socket(fd) == -1) {
+        ngx_free_connection(c);
+
+        c->fd = (ngx_socket_t) -1;
+
+        if (ngx_close_socket(ls[i].fd) == -1) {
             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                           ngx_close_socket_n " %V failed", &ls[i].addr_text);
         }
+    }
+}
 
-        cycle->connections[fd].fd = (ngx_socket_t) -1;
+
+ngx_connection_t *
+ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
+{
+    ngx_connection_t *c;
+
+    /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */
+
+    if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
+        ngx_log_error(NGX_LOG_ALERT, log, 0,
+                      "the new socket has number %d, "
+                      "but only %ui files are available",
+                      s, ngx_cycle->files_n);
+        return NULL;
+    }
+
+    /* ngx_mutex_lock */
+
+    c = ngx_cycle->free_connections;
+
+    if (c == NULL) {
+        ngx_log_error(NGX_LOG_ALERT, log, 0,
+                      "%ui worker_connections is not enough",
+                      ngx_cycle->connection_n);
+
+        /* ngx_mutex_unlock */
+
+        return NULL;
+    }
+
+    ngx_cycle->free_connections = c->data;
+    ngx_cycle->free_connection_n--;
+
+    /* ngx_mutex_unlock */
+
+    if (ngx_cycle->files) {
+        ngx_cycle->files[s] = c;
+    }
+
+    return c;
+}
+
+
+void
+ngx_free_connection(ngx_connection_t *c)
+{
+    /* ngx_mutex_lock */
+
+    c->data = ngx_cycle->free_connections;
+    ngx_cycle->free_connections = c;
+    ngx_cycle->free_connection_n++;
+
+    /* ngx_mutex_unlock */
+
+    if (ngx_cycle->files) {
+        ngx_cycle->files[c->fd] = NULL;
     }
 }
 
@@ -451,9 +504,10 @@ ngx_close_connection(ngx_connection_t *c
 
 #endif
 
+    ngx_free_connection(c);
+
     fd = c->fd;
     c->fd = (ngx_socket_t) -1;
-    c->data = NULL;
 
     if (ngx_close_socket(fd) == -1) {