comparison 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
comparison
equal deleted inserted replaced
562:4b6108f69026 563:9c2f3ed7a247
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 #include <ngx_iocp_module.h> 10 #include <ngx_iocp_module.h>
11 11
12 12
13 static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle); 13 static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer);
14 static ngx_thread_value_t __stdcall ngx_iocp_timer(void *data);
14 static void ngx_iocp_done(ngx_cycle_t *cycle); 15 static void ngx_iocp_done(ngx_cycle_t *cycle);
15 static ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key); 16 static ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key);
16 static ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, u_int flags); 17 static ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, u_int flags);
17 static ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle); 18 static ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
19 ngx_uint_t flags);
18 static void *ngx_iocp_create_conf(ngx_cycle_t *cycle); 20 static void *ngx_iocp_create_conf(ngx_cycle_t *cycle);
19 static char *ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf); 21 static char *ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf);
20 22
21 23
22 static ngx_str_t iocp_name = ngx_string("iocp"); 24 static ngx_str_t iocp_name = ngx_string("iocp");
91 ngx_overlapped_wsasend_chain, 93 ngx_overlapped_wsasend_chain,
92 0 94 0
93 }; 95 };
94 96
95 97
96 static HANDLE iocp; 98 static HANDLE iocp;
99 static ngx_tid_t timer_thread;
100 static ngx_msec_t msec;
97 101
98 102
99 static ngx_int_t 103 static ngx_int_t
100 ngx_iocp_init(ngx_cycle_t *cycle) 104 ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer)
101 { 105 {
102 ngx_iocp_conf_t *cf; 106 ngx_iocp_conf_t *cf;
103 107
104 cf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module); 108 cf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
105 109
107 iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 111 iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
108 cf->threads); 112 cf->threads);
109 } 113 }
110 114
111 if (iocp == NULL) { 115 if (iocp == NULL) {
112 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, 116 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
113 "CreateIoCompletionPort() failed"); 117 "CreateIoCompletionPort() failed");
114 return NGX_ERROR; 118 return NGX_ERROR;
115 } 119 }
116 120
117 ngx_io = ngx_iocp_io; 121 ngx_io = ngx_iocp_io;
118 122
119 ngx_event_actions = ngx_iocp_module_ctx.actions; 123 ngx_event_actions = ngx_iocp_module_ctx.actions;
120 124
121 ngx_event_flags = NGX_USE_AIO_EVENT|NGX_USE_IOCP_EVENT; 125 ngx_event_flags = NGX_USE_AIO_EVENT|NGX_USE_IOCP_EVENT;
122 126
127 if (timer == 0) {
128 return NGX_OK;
129 }
130
131 /*
132 * The waitable timer could not be used, because
133 * GetQueuedCompletionStatus() does not set a thread to alertable state
134 */
135
136 if (timer_thread == NULL) {
137
138 msec = timer;
139
140 if (ngx_create_thread(&timer_thread, ngx_iocp_timer, &msec, cycle->log)
141 != 0)
142 {
143 return NGX_ERROR;
144 }
145 }
146
147 ngx_event_flags |= NGX_USE_TIMER_EVENT;
148
123 return NGX_OK; 149 return NGX_OK;
150 }
151
152
153 static ngx_thread_value_t __stdcall
154 ngx_iocp_timer(void *data)
155 {
156 ngx_msec_t timer = *(ngx_msec_t *) data;
157
158 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
159 "THREAD %p %p", &msec, data);
160
161 for ( ;; ) {
162 Sleep(timer);
163
164 ngx_time_update(0, 0);
165 #if 1
166 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer");
167 #endif
168 }
169
170 #ifdef __WATCOMC__
171 return 0;
172 #endif
124 } 173 }
125 174
126 175
127 static void 176 static void
128 ngx_iocp_done(ngx_cycle_t *cycle) 177 ngx_iocp_done(ngx_cycle_t *cycle)
176 return NGX_OK; 225 return NGX_OK;
177 } 226 }
178 227
179 228
180 static 229 static
181 ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle) 230 ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
231 ngx_uint_t flags)
182 { 232 {
183 int rc; 233 int rc;
184 u_int key; 234 u_int key;
185 u_long bytes; 235 u_long bytes;
186 ngx_err_t err; 236 ngx_err_t err;
187 ngx_msec_t timer, delta; 237 ngx_msec_t delta;
188 ngx_event_t *ev; 238 ngx_event_t *ev;
189 struct timeval tv;
190 ngx_event_ovlp_t *ovlp; 239 ngx_event_ovlp_t *ovlp;
191
192 timer = ngx_event_find_timer();
193 240
194 if (timer == NGX_TIMER_INFINITE) { 241 if (timer == NGX_TIMER_INFINITE) {
195 timer = INFINITE; 242 timer = INFINITE;
196 } 243 }
197 244
204 err = ngx_errno; 251 err = ngx_errno;
205 } else { 252 } else {
206 err = 0; 253 err = 0;
207 } 254 }
208 255
209 ngx_gettimeofday(&tv); 256 delta = ngx_current_msec;
210 ngx_time_update(tv.tv_sec); 257
258 if (flags & NGX_UPDATE_TIME) {
259 ngx_time_update(0, 0);
260 }
211 261
212 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 262 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
213 "iocp: %d b:%d k:%d ov:%p", rc, bytes, key, ovlp); 263 "iocp: %d b:%d k:%d ov:%p", rc, bytes, key, ovlp);
214 264
215 delta = ngx_current_time;
216 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
217
218 if (timer != INFINITE) { 265 if (timer != INFINITE) {
219 delta = ngx_current_time - delta; 266 delta = ngx_current_msec - delta;
220 267
221 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 268 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
222 "iocp timer: %M, delta: %M", timer, delta); 269 "iocp timer: %M, delta: %M", timer, delta);
223 } 270 }
224 271
229 "GetQueuedCompletionStatus() failed"); 276 "GetQueuedCompletionStatus() failed");
230 277
231 return NGX_ERROR; 278 return NGX_ERROR;
232 } 279 }
233 280
234 ngx_event_expire_timers();
235
236 return NGX_OK; 281 return NGX_OK;
237 } 282 }
238 283
239 ovlp->error = err; 284 ovlp->error = err;
240 } 285 }
260 * for a file descriptor that was closed 305 * for a file descriptor that was closed
261 */ 306 */
262 307
263 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err, 308 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err,
264 "iocp: aborted event %p", ev); 309 "iocp: aborted event %p", ev);
265
266 ngx_event_expire_timers();
267 310
268 return NGX_OK; 311 return NGX_OK;
269 } 312 }
270 313
271 if (err) { 314 if (err) {
295 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 338 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
296 "iocp event handler: %p", ev->handler); 339 "iocp event handler: %p", ev->handler);
297 340
298 ev->handler(ev); 341 ev->handler(ev);
299 342
300 ngx_event_expire_timers();
301
302 return NGX_OK; 343 return NGX_OK;
303 } 344 }
304 345
305 346
306 static void * 347 static void *