diff src/event/modules/ngx_iocp_module.c @ 563:9c2f3ed7a247 release-0.3.3

nginx-0.3.3-RELEASE import *) 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; the bug had 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 <igor@sysoev.ru>
date Wed, 19 Oct 2005 12:33:58 +0000
parents ecd9c160f25b
children 4d9ea73a627a
line wrap: on
line diff
--- a/src/event/modules/ngx_iocp_module.c
+++ b/src/event/modules/ngx_iocp_module.c
@@ -10,11 +10,13 @@
 #include <ngx_iocp_module.h>
 
 
-static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle);
+static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer);
+static ngx_thread_value_t __stdcall ngx_iocp_timer(void *data);
 static void ngx_iocp_done(ngx_cycle_t *cycle);
 static ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key);
 static ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, u_int flags);
-static ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle);
+static ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
+    ngx_uint_t flags);
 static void *ngx_iocp_create_conf(ngx_cycle_t *cycle);
 static char *ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf);
 
@@ -93,11 +95,13 @@ ngx_os_io_t ngx_iocp_io = {
 };
 
 
-static HANDLE  iocp;
+static HANDLE      iocp;
+static ngx_tid_t   timer_thread;
+static ngx_msec_t  msec;
 
 
 static ngx_int_t
-ngx_iocp_init(ngx_cycle_t *cycle)
+ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer)
 {
     ngx_iocp_conf_t  *cf;
 
@@ -109,7 +113,7 @@ ngx_iocp_init(ngx_cycle_t *cycle)
     }
 
     if (iocp == NULL) {
-        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                       "CreateIoCompletionPort() failed");
         return NGX_ERROR;
     }
@@ -120,10 +124,55 @@ ngx_iocp_init(ngx_cycle_t *cycle)
 
     ngx_event_flags = NGX_USE_AIO_EVENT|NGX_USE_IOCP_EVENT;
 
+    if (timer == 0) {
+        return NGX_OK;
+    }
+
+    /*
+     * The waitable timer could not be used, because
+     * GetQueuedCompletionStatus() does not set a thread to alertable state
+     */
+
+    if (timer_thread == NULL) {
+
+        msec = timer;
+
+        if (ngx_create_thread(&timer_thread, ngx_iocp_timer, &msec, cycle->log)
+            != 0)
+        {
+            return NGX_ERROR;
+        }
+    }
+
+    ngx_event_flags |= NGX_USE_TIMER_EVENT;
+
     return NGX_OK;
 }
 
 
+static ngx_thread_value_t __stdcall
+ngx_iocp_timer(void *data)
+{
+    ngx_msec_t  timer = *(ngx_msec_t *) data;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
+                   "THREAD %p %p", &msec, data);
+
+    for ( ;; ) {
+        Sleep(timer);
+
+        ngx_time_update(0, 0);
+#if 1
+        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer");
+#endif
+    }
+
+#ifdef __WATCOMC__
+    return 0;
+#endif
+}
+
+
 static void
 ngx_iocp_done(ngx_cycle_t *cycle)
 {
@@ -178,19 +227,17 @@ ngx_iocp_del_connection(ngx_connection_t
 
 
 static
-ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle)
+ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
+    ngx_uint_t flags)
 {
     int                rc;
     u_int              key;
     u_long             bytes;
     ngx_err_t          err;
-    ngx_msec_t         timer, delta;
+    ngx_msec_t         delta;
     ngx_event_t       *ev;
-    struct timeval     tv;
     ngx_event_ovlp_t  *ovlp;
 
-    timer = ngx_event_find_timer();
-
     if (timer == NGX_TIMER_INFINITE) {
         timer = INFINITE;
     }
@@ -206,17 +253,17 @@ ngx_int_t ngx_iocp_process_events(ngx_cy
         err = 0;
     }
 
-    ngx_gettimeofday(&tv);
-    ngx_time_update(tv.tv_sec);
+    delta = ngx_current_msec;
+    
+    if (flags & NGX_UPDATE_TIME) {
+        ngx_time_update(0, 0);
+    }
 
     ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    "iocp: %d b:%d k:%d ov:%p", rc, bytes, key, ovlp);
 
-    delta = ngx_current_time;
-    ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
-
     if (timer != INFINITE) {
-        delta = ngx_current_time - delta;
+        delta = ngx_current_msec - delta;
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                        "iocp timer: %M, delta: %M", timer, delta);
@@ -231,8 +278,6 @@ ngx_int_t ngx_iocp_process_events(ngx_cy
                 return NGX_ERROR;
             }
 
-            ngx_event_expire_timers();
-
             return NGX_OK;
         }
 
@@ -263,8 +308,6 @@ ngx_int_t ngx_iocp_process_events(ngx_cy
         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err,
                        "iocp: aborted event %p", ev); 
 
-        ngx_event_expire_timers();
-
         return NGX_OK;
     }
 
@@ -297,8 +340,6 @@ ngx_int_t ngx_iocp_process_events(ngx_cy
 
     ev->handler(ev);
 
-    ngx_event_expire_timers();
-
     return NGX_OK;
 }