Mercurial > hg > nginx
comparison src/event/modules/ngx_iocp_module.c @ 102:7e86d028d8f0
nginx-0.0.1-2003-06-06-18:59:20 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 06 Jun 2003 14:59:20 +0000 |
parents | 19cc647ecd91 |
children | 6dfda4cf5200 |
comparison
equal
deleted
inserted
replaced
101:2e069b6e6920 | 102:7e86d028d8f0 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru | |
4 */ | |
5 | |
1 | 6 |
2 #include <ngx_config.h> | 7 #include <ngx_config.h> |
3 | |
4 #include <ngx_core.h> | 8 #include <ngx_core.h> |
5 #include <ngx_log.h> | |
6 #include <ngx_errno.h> | |
7 #include <ngx_time.h> | |
8 #include <ngx_connection.h> | |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 #include <ngx_event_timer.h> | 10 |
11 | 11 |
12 #include <ngx_iocp_module.h> | 12 typedef struct { |
13 | 13 int threads; |
14 | 14 } ngx_iocp_conf_t; |
15 int ngx_iocp_threads = 0;; | 15 |
16 | 16 |
17 | 17 static int ngx_iocp_init(ngx_log_t *log); |
18 static HANDLE iocp; | 18 static void ngx_iocp_done(ngx_log_t *log); |
19 static ngx_event_t *timer_queue; | 19 static int ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key); |
20 | 20 static int ngx_iocp_process_events(ngx_log_t *log); |
21 | 21 static void *ngx_iocp_create_conf(ngx_pool_t *pool); |
22 int ngx_iocp_init(int max_connections, ngx_log_t *log) | 22 static char *ngx_iocp_init_conf(ngx_pool_t *pool, void *conf); |
23 { | 23 |
24 iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, | 24 |
25 NULL, 0, ngx_iocp_threads); | 25 static ngx_str_t iocp_name = ngx_string("iocp"); |
26 | |
27 static ngx_command_t ngx_iocp_commands[] = { | |
28 | |
29 {ngx_string("iocp_threads"), | |
30 NGX_EVENT_CONF|NGX_CONF_TAKE1, | |
31 ngx_conf_set_num_slot, | |
32 0, | |
33 offsetof(ngx_iocp_conf_t, threads), | |
34 NULL}, | |
35 | |
36 ngx_null_command | |
37 }; | |
38 | |
39 | |
40 ngx_event_module_t ngx_iocp_module_ctx = { | |
41 &iocp_name, | |
42 ngx_iocp_create_conf, /* create configuration */ | |
43 ngx_iocp_init_conf, /* init configuration */ | |
44 | |
45 { | |
46 ngx_iocp_add_event, /* add an event */ | |
47 NULL, /* delete an event */ | |
48 NULL, /* enable an event */ | |
49 NULL, /* disable an event */ | |
50 NULL, /* add an connection */ | |
51 NULL, /* delete an connection */ | |
52 ngx_iocp_process_events, /* process the events */ | |
53 ngx_iocp_init, /* init the events */ | |
54 ngx_iocp_done /* done the events */ | |
55 } | |
56 | |
57 }; | |
58 | |
59 ngx_module_t ngx_iocp_module = { | |
60 NGX_MODULE, | |
61 &ngx_iocp_module_ctx, /* module context */ | |
62 ngx_iocp_commands, /* module directives */ | |
63 NGX_EVENT_MODULE, /* module type */ | |
64 NULL /* init module */ | |
65 }; | |
66 | |
67 | |
68 static HANDLE iocp; | |
69 | |
70 | |
71 static int ngx_iocp_init(ngx_log_t *log) | |
72 { | |
73 ngx_iocp_conf_t *cf; | |
74 | |
75 cf = ngx_event_get_conf(ngx_iocp_module); | |
76 | |
77 iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, cf->threads); | |
26 | 78 |
27 if (iocp == NULL) { | 79 if (iocp == NULL) { |
28 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, | 80 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, |
29 "CreateIoCompletionPort() failed"); | 81 "CreateIoCompletionPort() failed"); |
30 return NGX_ERROR; | 82 return NGX_ERROR; |
31 } | 83 } |
32 | 84 |
33 timer_queue = ngx_event_init_timer(log); | 85 if (ngx_event_timer_init(log) == NGX_ERROR) { |
34 if (timer_queue == NULL) { | |
35 return NGX_ERROR; | 86 return NGX_ERROR; |
36 } | 87 } |
37 | 88 |
38 ngx_event_actions.process = ngx_iocp_process_events; | 89 ngx_event_actions = ngx_iocp_module_ctx.actions; |
39 | 90 |
40 ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_HAVE_IOCP_EVENT; | 91 ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_HAVE_IOCP_EVENT; |
41 | 92 |
42 return NGX_OK; | 93 return NGX_OK; |
43 } | 94 } |
44 | 95 |
45 | 96 |
46 int ngx_iocp_add_event(ngx_event_t *ev) | 97 static void ngx_iocp_done(ngx_log_t *log) |
98 { | |
99 if (CloseHandle(iocp) == -1) { | |
100 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
101 "iocp CloseHandle() failed"); | |
102 } | |
103 | |
104 ngx_event_timer_done(log); | |
105 } | |
106 | |
107 | |
108 static int ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key) | |
47 { | 109 { |
48 ngx_connection_t *c; | 110 ngx_connection_t *c; |
49 | 111 |
50 c = (ngx_connection_t *) ev->data; | 112 c = (ngx_connection_t *) ev->data; |
51 | 113 |
52 ngx_log_debug(ev->log, "iocp: %d, %08x:%08x" _ c->fd _ ev _ &ev->ovlp); | 114 ngx_log_debug(ev->log, "iocp add: %d, %08x:%08x" _ c->fd _ key _ &ev->ovlp); |
53 | 115 |
54 if (CreateIoCompletionPort((HANDLE) c->fd, iocp, (DWORD) ev, 0) == NULL) { | 116 if (CreateIoCompletionPort((HANDLE) c->fd, iocp, key, 0) == NULL) { |
55 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | 117 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, |
56 "CreateIoCompletionPort() failed"); | 118 "CreateIoCompletionPort() failed"); |
57 return NGX_ERROR; | 119 return NGX_ERROR; |
58 } | 120 } |
59 | 121 |
60 return NGX_OK; | 122 return NGX_OK; |
61 } | 123 } |
62 | 124 |
63 | 125 |
64 int ngx_iocp_process_events(ngx_log_t *log) | 126 static int ngx_iocp_process_events(ngx_log_t *log) |
65 { | 127 { |
66 int rc; | 128 int rc; |
129 u_int key; | |
67 size_t bytes; | 130 size_t bytes; |
68 ngx_err_t err; | 131 ngx_err_t err; |
69 ngx_msec_t timer, delta; | 132 ngx_msec_t timer, delta; |
70 ngx_event_t *ev, *e; | 133 ngx_event_t *ev; |
71 ngx_event_ovlp_t *ovlp; | 134 ngx_event_ovlp_t *ovlp; |
72 | |
73 ngx_log_debug(log, "iocp"); | |
74 | 135 |
75 timer = ngx_event_find_timer(); | 136 timer = ngx_event_find_timer(); |
76 | 137 |
77 if (timer) { | 138 if (timer) { |
78 delta = ngx_msec(); | 139 delta = ngx_msec(); |
82 delta = 0; | 143 delta = 0; |
83 } | 144 } |
84 | 145 |
85 ngx_log_debug(log, "iocp timer: %d" _ timer); | 146 ngx_log_debug(log, "iocp timer: %d" _ timer); |
86 | 147 |
87 #if 1 | 148 rc = GetQueuedCompletionStatus(iocp, &bytes, (LPDWORD) &key, |
88 rc = GetQueuedCompletionStatus(iocp, &bytes, (LPDWORD) &e, | |
89 (LPOVERLAPPED *) &ovlp, timer); | 149 (LPOVERLAPPED *) &ovlp, timer); |
90 ngx_log_debug(log, "iocp: %d, %d:%08x:%08x" _ rc _ bytes _ e _ ovlp); | 150 |
151 ngx_log_debug(log, "iocp: %d, %d:%08x:%08x" _ rc _ bytes _ key _ ovlp); | |
152 | |
91 if (rc == 0) { | 153 if (rc == 0) { |
92 #else | |
93 if (GetQueuedCompletionStatus(iocp, &bytes, (LPDWORD) &e, | |
94 (LPOVERLAPPED *) &ovlp, timer) == 0) { | |
95 #endif | |
96 err = ngx_errno; | 154 err = ngx_errno; |
97 | 155 |
98 if (ovlp == NULL) { | 156 if (ovlp == NULL) { |
99 if (err != WAIT_TIMEOUT) { | 157 if (err != WAIT_TIMEOUT) { |
100 ngx_log_error(NGX_LOG_ALERT, log, err, | 158 ngx_log_error(NGX_LOG_ALERT, log, err, |
116 if (ovlp) { | 174 if (ovlp) { |
117 ev = ovlp->event; | 175 ev = ovlp->event; |
118 | 176 |
119 ngx_log_debug(log, "iocp ev: %08x" _ ev); | 177 ngx_log_debug(log, "iocp ev: %08x" _ ev); |
120 | 178 |
121 if (ev == e) { | 179 switch (key) { |
122 /* it's not AcceptEx() completion */ | 180 case NGX_IOCP_IO: |
123 ev->ready = 1; | 181 ev->ready = 1; |
124 ev->available = bytes; | 182 ev->available = bytes; |
183 break; | |
184 | |
185 case NGX_IOCP_ACCEPT: | |
186 break; | |
125 } | 187 } |
126 | 188 |
127 ngx_log_debug(log, "iocp ev: %08x" _ ev->event_handler); | 189 ngx_log_debug(log, "iocp ev handler: %08x" _ ev->event_handler); |
128 | 190 |
129 ev->event_handler(ev); | 191 ev->event_handler(ev); |
130 } | 192 } |
131 | 193 |
132 return NGX_OK; | 194 return NGX_OK; |
133 } | 195 } |
196 | |
197 | |
198 static void *ngx_iocp_create_conf(ngx_pool_t *pool) | |
199 { | |
200 ngx_iocp_conf_t *cf; | |
201 | |
202 ngx_test_null(cf, ngx_palloc(pool, sizeof(ngx_iocp_conf_t)), | |
203 NGX_CONF_ERROR); | |
204 | |
205 cf->threads = NGX_CONF_UNSET; | |
206 | |
207 return cf; | |
208 } | |
209 | |
210 | |
211 static char *ngx_iocp_init_conf(ngx_pool_t *pool, void *conf) | |
212 { | |
213 ngx_iocp_conf_t *cf = conf; | |
214 | |
215 ngx_conf_init_value(cf->threads, 0); | |
216 | |
217 return NGX_CONF_OK; | |
218 } |