diff src/event/ngx_event.c @ 112:408f195b3482 NGINX_0_3_3

nginx 0.3.3 *) Change: the "bl" and "af" parameters of the "listen" directive was renamed to the "backlog" and "accept_filter". *) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen" directive. *) Change: the "$msec" log parameter does not require now the additional the gettimeofday() system call. *) Feature: the -t switch now tests the "listen" directives. *) Bugfix: if the invalid address was specified in the "listen" directive, then after the -HUP signal nginx left an open socket in the CLOSED state. *) Bugfix: the mime type may be incorrectly set to default value for index file with variable in the name; bug appeared in 0.3.0. *) Feature: the "timer_resolution" directive. *) Feature: the millisecond "$upstream_response_time" log parameter. *) Bugfix: a temporary file with client request body now is removed just after the response header was transferred to a client. *) Bugfix: OpenSSL 0.9.6 compatibility. *) Bugfix: the SSL certificate and key file paths could not be relative. *) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in the ngx_imap_ssl_module. *) Bugfix: the "ssl_protocols" directive allowed to specify the single protocol only.
author Igor Sysoev <http://sysoev.ru>
date Wed, 19 Oct 2005 00:00:00 +0400
parents dad2fe8ecf08
children e38f51cd0905
line wrap: on
line diff
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -34,6 +34,9 @@ static char *ngx_event_init_conf(ngx_cyc
 static char *ngx_accept_mutex_check(ngx_conf_t *cf, void *post, void *data);
 
 
+static ngx_uint_t     ngx_timer_resolution;
+sig_atomic_t          ngx_event_timer_alarm;
+
 static ngx_uint_t     ngx_event_max_module;
 
 ngx_uint_t            ngx_event_flags;
@@ -192,6 +195,77 @@ ngx_module_t  ngx_event_core_module = {
 };
 
 
+void
+ngx_process_events_and_timers(ngx_cycle_t *cycle)
+{
+    ngx_uint_t  flags;
+    ngx_msec_t  timer;
+
+    if (ngx_timer_resolution) {
+        timer = NGX_TIMER_INFINITE;
+        flags = 0;
+
+    } else {
+        timer = ngx_event_find_timer();
+        flags = NGX_UPDATE_TIME;
+
+#if (NGX_THREADS)
+
+        if (timer == NGX_TIMER_INFINITE || timer > 500) {
+            timer = 500;
+        }
+
+#endif
+    }
+
+    if (ngx_accept_mutex) {
+        if (ngx_accept_disabled > 0) {
+            ngx_accept_disabled--;
+
+        } else {
+            if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
+                return;
+            }
+
+            if (ngx_accept_mutex_held) {
+                flags |= NGX_POST_EVENTS;
+
+            } else {
+                if (timer == NGX_TIMER_INFINITE
+                    || timer > ngx_accept_mutex_delay)
+                {
+                    timer = ngx_accept_mutex_delay;
+                }
+            }
+        }
+    }
+
+    (void) ngx_process_events(cycle, timer, flags);
+
+    ngx_event_expire_timers();
+
+    if (ngx_posted_accept_events) {
+        ngx_event_process_posted(cycle, &ngx_posted_accept_events);
+    }
+
+    if (ngx_accept_mutex_held) {
+        ngx_accept_mutex = 0;
+    }
+
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                   "posted events %p", ngx_posted_events);
+
+    if (ngx_posted_events) {
+        if (ngx_threaded) {
+            ngx_wakeup_worker_thread(cycle);
+
+        } else {
+            ngx_event_process_posted(cycle, &ngx_posted_events);
+        }
+    }
+}
+
+
 ngx_int_t
 ngx_handle_read_event(ngx_event_t *rev, u_int flags)
 {
@@ -332,12 +406,12 @@ ngx_event_module_init(ngx_cycle_t *cycle
 {
     void              ***cf;
     ngx_event_conf_t    *ecf;
+    ngx_core_conf_t     *ccf;
 #if !(NGX_WIN32)
     char                *shared;
     size_t               size;
     ngx_int_t            limit;
     struct rlimit        rlmt;
-    ngx_core_conf_t     *ccf;
 #endif
 
     cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module);
@@ -353,9 +427,11 @@ ngx_event_module_init(ngx_cycle_t *cycle
     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
                   "using the \"%s\" event method", ecf->name);
 
-#if !(NGX_WIN32)
+    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
 
-    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+    ngx_timer_resolution = ccf->timer_resolution;
+
+#if !(NGX_WIN32)
 
     if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
@@ -417,6 +493,8 @@ ngx_event_module_init(ngx_cycle_t *cycle
 
 #endif
 
+    *ngx_connection_counter = 1;
+
     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    "counter: %p, %d",
                    ngx_connection_counter, *ngx_connection_counter);
@@ -427,6 +505,23 @@ ngx_event_module_init(ngx_cycle_t *cycle
 }
 
 
+#if !(NGX_WIN32)
+
+void
+ngx_timer_signal_handler(int signo)
+{
+    ngx_event_timer_alarm = 1;
+
+    ngx_time_update(0, 0);
+
+#if 1
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
+#endif
+}
+
+#endif
+
+
 static ngx_int_t
 ngx_event_process_init(ngx_cycle_t *cycle)
 {
@@ -441,6 +536,8 @@ ngx_event_process_init(ngx_cycle_t *cycl
     ngx_iocp_conf_t     *iocpcf;
 #else
     struct rlimit        rlmt;
+    struct sigaction     sa;
+    struct itimerval     itv;
 #endif
 
     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
@@ -473,7 +570,8 @@ ngx_event_process_init(ngx_cycle_t *cycl
 
         if (ngx_modules[m]->ctx_index == ecf->use) {
             module = ngx_modules[m]->ctx;
-            if (module->actions.init(cycle) == NGX_ERROR) {
+            if (module->actions.init(cycle, ngx_timer_resolution) == NGX_ERROR)
+            {
                 /* fatal */
                 exit(2);
             }
@@ -483,6 +581,29 @@ ngx_event_process_init(ngx_cycle_t *cycl
 
 #if !(NGX_WIN32)
 
+    if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
+
+        ngx_memzero(&sa, sizeof(struct sigaction));
+        sa.sa_handler = ngx_timer_signal_handler;
+        sigemptyset(&sa.sa_mask);
+
+        if (sigaction(SIGALRM, &sa, NULL) == -1) {
+            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                          "sigaction(SIGALRM) failed");
+            return NGX_ERROR;
+        }
+
+        itv.it_interval.tv_sec = ngx_timer_resolution / 1000;
+        itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000;
+        itv.it_value.tv_sec = ngx_timer_resolution / 1000;
+        itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000;
+
+        if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
+            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                          "setitimer() failed");
+        } 
+    }
+
     if (ngx_event_flags & NGX_USE_FD_EVENT) {
 
         if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {