comparison src/event/modules/ngx_select_module.c @ 8:708f8bb772ec

nginx-0.0.1-2002-09-02-18:48:24 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 02 Sep 2002 14:48:24 +0000
parents b5481d6fbbd4
children 2aba961a1d34
comparison
equal deleted inserted replaced
7:b5481d6fbbd4 8:708f8bb772ec
1 1
2 #include <ngx_config.h> 2 #include <ngx_config.h>
3 #include <ngx_core.h>
3 #include <ngx_types.h> 4 #include <ngx_types.h>
4 #include <ngx_log.h> 5 #include <ngx_log.h>
5 #include <ngx_time.h> 6 #include <ngx_time.h>
6 #include <ngx_connection.h> 7 #include <ngx_connection.h>
7 #include <ngx_event.h> 8 #include <ngx_event.h>
8 #include <ngx_select_module.h> 9 #include <ngx_select_module.h>
9 10
10 static fd_set master_read_fds; 11 static fd_set master_read_fd_set;
11 static fd_set master_write_fds; 12 static fd_set master_write_fd_set;
12 static fd_set work_read_fds; 13 static fd_set work_read_fd_set;
13 static fd_set work_write_fds; 14 static fd_set work_write_fd_set;
14 15
15 #if (WIN32) 16 #if (WIN32)
16 static int max_read; 17 static int max_read;
17 static int max_write; 18 static int max_write;
18 #else 19 #else
21 22
22 static ngx_event_t event_queue; 23 static ngx_event_t event_queue;
23 static ngx_event_t timer_queue; 24 static ngx_event_t timer_queue;
24 25
25 26
26 static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
27
28 static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event, 27 static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event,
29 ngx_log_t *log); 28 ngx_log_t *log);
30 29
31 void ngx_select_init(int max_connections, ngx_log_t *log) 30 void ngx_select_init(int max_connections, ngx_log_t *log)
32 { 31 {
40 "supported by select() is %d", FD_SETSIZE - 1); 39 "supported by select() is %d", FD_SETSIZE - 1);
41 #endif 40 #endif
42 exit(1); 41 exit(1);
43 } 42 }
44 43
45 FD_ZERO(&master_read_fds); 44 FD_ZERO(&master_read_fd_set);
46 FD_ZERO(&master_write_fds); 45 FD_ZERO(&master_write_fd_set);
47 46
48 event_queue.prev = &event_queue; 47 event_queue.prev = &event_queue;
49 event_queue.next = &event_queue; 48 event_queue.next = &event_queue;
50 49
51 timer_queue.timer_prev = &timer_queue; 50 timer_queue.timer_prev = &timer_queue;
52 timer_queue.timer_next = &timer_queue; 51 timer_queue.timer_next = &timer_queue;
53 52
54 ngx_event_actions.add = ngx_select_add_event; 53 ngx_event_actions.add = ngx_select_add_event;
55 ngx_event_actions.del = ngx_select_del_event; 54 ngx_event_actions.del = ngx_select_del_event;
55 ngx_event_actions.timer = ngx_select_add_timer;
56 ngx_event_actions.process = ngx_select_process_events; 56 ngx_event_actions.process = ngx_select_process_events;
57 57
58 #if (WIN32) 58 #if (WIN32)
59 max_read = max_write = 0; 59 max_read = max_write = 0;
60 #else 60 #else
62 #endif 62 #endif
63 } 63 }
64 64
65 int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) 65 int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags)
66 { 66 {
67 fd_set *fds; 67 ngx_connection_t *c;
68 ngx_connection_t *cn = (ngx_connection_t *) ev->data; 68
69 69 c = (ngx_connection_t *) ev->data;
70 if (event == NGX_TIMER_EVENT) { 70
71 ngx_add_timer_core(ev, flags); 71 ngx_log_debug(ev->log, "select fd:%d event:%d" _ c->fd _ event);
72 return 0; 72
73 } 73 #if (WIN32)
74 74 if ((event == NGX_READ_EVENT) && (max_read >= FD_SETSIZE)
75 ngx_assert((flags != NGX_ONESHOT_EVENT), return -1, ev->log, 75 || (event == NGX_WRITE_EVENT) && (max_write >= FD_SETSIZE))
76 "ngx_select_add_event: NGX_ONESHOT_EVENT is not supported"); 76 {
77 77 ngx_log_error(NGX_LOG_ERR, ev->log, 0,
78 fds = ngx_select_get_fd_set(cn->fd, event, ev->log); 78 "maximum number of descriptors "
79 if (fds == NULL) 79 "supported by select() is %d", FD_SETSIZE);
80 return -1; 80 return NGX_ERROR;
81 }
82
83 if (event == NGX_READ_EVENT) {
84 FD_SET(c->fd, &master_read_fd_set);
85 max_read++;
86
87 } else if (event == NGX_WRITE_EVENT) {
88 FD_SET(c->fd, &master_write_fd_set);
89 max_write++;
90 }
91 #else
92 if (event == NGX_READ_EVENT)
93 FD_SET(c->fd, &master_read_fd_set);
94
95 else if (event == NGX_WRITE_EVENT)
96 FD_SET(c->fd, &master_write_fd_set);
97
98 if (max_fd != -1 && max_fd < c->fd)
99 max_fd = c->fd;
100
101 #endif
102
103 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
81 104
82 ev->prev = &event_queue; 105 ev->prev = &event_queue;
83 ev->next = event_queue.next; 106 ev->next = event_queue.next;
84 event_queue.next->prev = ev; 107 event_queue.next->prev = ev;
85 event_queue.next = ev; 108 event_queue.next = ev;
86 109
87 FD_SET(cn->fd, fds); 110 return NGX_OK;
88
89 #if (WIN32)
90 switch (event) {
91 case NGX_READ_EVENT:
92 max_read++;
93 break;
94 case NGX_WRITE_EVENT:
95 max_write++;
96 break;
97 }
98 #else
99 if (max_fd != -1 && max_fd < cn->fd)
100 max_fd = cn->fd;
101 #endif
102
103 return 0;
104 } 111 }
105 112
106 int ngx_select_del_event(ngx_event_t *ev, int event) 113 int ngx_select_del_event(ngx_event_t *ev, int event)
107 { 114 {
108 fd_set *fds; 115 ngx_connection_t *c;
109 ngx_connection_t *cn = (ngx_connection_t *) ev->data; 116 c = (ngx_connection_t *) ev->data;
110 117
111 if (event == NGX_TIMER_EVENT) { 118 #if (WIN32)
112 ngx_del_timer(ev); 119 if (event == NGX_READ_EVENT) {
113 return 0; 120 FD_CLR(c->fd, &master_read_fd_set);
114 } 121 max_read--;
115 122
116 fds = ngx_select_get_fd_set(cn->fd, event, ev->log); 123 } else if (event == NGX_WRITE_EVENT) {
117 if (fds == NULL) 124 FD_CLR(c->fd, &master_write_fd_set);
118 return -1; 125 max_write--;
126 }
127 #else
128 if (event == NGX_READ_EVENT)
129 FD_CLR(c->fd, &master_read_fd_set);
130
131 else if (event == NGX_WRITE_EVENT)
132 FD_CLR(c->fd, &master_write_fd_set);
133
134 if (max_fd == c->fd)
135 max_fd = -1;
136 #endif
119 137
120 if (ev->prev) 138 if (ev->prev)
121 ev->prev->next = ev->next; 139 ev->prev->next = ev->next;
122 140
123 if (ev->next) { 141 if (ev->next) {
126 } 144 }
127 145
128 if (ev->prev) 146 if (ev->prev)
129 ev->next = NULL; 147 ev->next = NULL;
130 148
131 FD_CLR(cn->fd, fds); 149 return NGX_OK;
132
133 #if (WIN32)
134 switch (event) {
135 case NGX_READ_EVENT:
136 max_read--;
137 break;
138 case NGX_WRITE_EVENT:
139 max_write--;
140 break;
141 }
142 #else
143 if (max_fd == cn->fd)
144 max_fd = -1;
145 #endif
146
147 return 0;
148 }
149
150 static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event, ngx_log_t *log)
151 {
152 ngx_log_debug(log, "ngx_select_get_fd_set: %d %d" _ fd _ event);
153
154 #if !(WIN32)
155 if (fd >= FD_SETSIZE) {
156 ngx_log_error(NGX_LOG_ERR, log, 0,
157 "ngx_select_get_event: maximum descriptor number"
158 "supported by select() is %d",
159 FD_SETSIZE - 1);
160 return NULL;
161 }
162 #endif
163
164 switch (event) {
165 case NGX_READ_EVENT:
166 #if (WIN32)
167 if (max_read >= FD_SETSIZE) {
168 ngx_log_error(NGX_LOG_ERR, log, 0,
169 "ngx_select_get_event: maximum number of descriptors "
170 "supported by select() is %d",
171 FD_SETSIZE);
172 return NULL;
173 }
174 #endif
175 return &master_read_fds;
176
177 case NGX_WRITE_EVENT:
178 #if (WIN32)
179 if (max_write >= FD_SETSIZE) {
180 ngx_log_error(NGX_LOG_ERR, log, 0,
181 "ngx_select_get_event: maximum number of descriptors "
182 "supported by select() is %d",
183 FD_SETSIZE);
184 return NULL;
185 }
186 #endif
187 return &master_write_fds;
188
189 default:
190 ngx_assert(0, return NULL, log,
191 "ngx_select_get_fd_set: invalid event %d" _ event);
192 }
193
194 return NULL;
195 } 150 }
196 151
197 int ngx_select_process_events(ngx_log_t *log) 152 int ngx_select_process_events(ngx_log_t *log)
198 { 153 {
199 int ready, found; 154 int ready, found;
200 u_int timer, delta; 155 u_int timer, delta;
201 ngx_event_t *ev, *nx; 156 ngx_event_t *ev, *nx;
202 ngx_connection_t *cn; 157 ngx_connection_t *c;
203 struct timeval tv, *tp; 158 struct timeval tv, *tp;
204 159
205 work_read_fds = master_read_fds; 160 work_read_fd_set = master_read_fd_set;
206 work_write_fds = master_write_fds; 161 work_write_fd_set = master_write_fd_set;
207 162
208 if (timer_queue.timer_next != &timer_queue) { 163 if (timer_queue.timer_next != &timer_queue) {
209 timer = timer_queue.timer_next->timer_delta; 164 timer = timer_queue.timer_next->timer_delta;
210 tv.tv_sec = timer / 1000; 165 tv.tv_sec = timer / 1000;
211 tv.tv_usec = (timer % 1000) * 1000; 166 tv.tv_usec = (timer % 1000) * 1000;
220 } 175 }
221 176
222 #if !(WIN32) 177 #if !(WIN32)
223 if (max_fd == -1) { 178 if (max_fd == -1) {
224 for (ev = event_queue.next; ev != &event_queue; ev = ev->next) { 179 for (ev = event_queue.next; ev != &event_queue; ev = ev->next) {
225 cn = (ngx_connection_t *) ev->data; 180 c = (ngx_connection_t *) ev->data;
226 if (max_fd < cn->fd) 181 if (max_fd < c->fd)
227 max_fd = cn->fd; 182 max_fd = c->fd;
228 } 183 }
229 184
230 ngx_log_debug(log, "ngx_select_process_events: change max_fd: %d" _ 185 ngx_log_debug(log, "change max_fd: %d" _ max_fd);
231 max_fd);
232 } 186 }
233 #endif 187 #endif
234 188
235 ngx_log_debug(log, "ngx_select_process_events: timer: %d" _ timer); 189 ngx_log_debug(log, "ngx_select_process_events: timer: %d" _ timer);
236 190
237 #if (WIN32) 191 #if (WIN32)
238 if ((ready = select(0, &work_read_fds, &work_write_fds, NULL, tp)) 192 if ((ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp))
239 #else 193 #else
240 if ((ready = select(max_fd + 1, &work_read_fds, &work_write_fds, NULL, tp)) 194 if ((ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set,
195 NULL, tp))
241 #endif 196 #endif
242 == -1) { 197 == -1) {
243 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, 198 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
244 "ngx_select_process_events: select failed"); 199 "ngx_select_process_events: select failed");
245 return -1; 200 return NGX_ERROR;
246 } 201 }
247 202
248 ngx_log_debug(log, "ngx_select_process_events: ready %d" _ ready); 203 ngx_log_debug(log, "ngx_select_process_events: ready %d" _ ready);
249 204
250 if (timer) { 205 if (timer) {
251 delta = ngx_msec() - delta; 206 delta = ngx_msec() - delta;
252 207
253 } else { 208 } else {
254 ngx_assert((ready != 0), return -1, log, 209 ngx_assert((ready != 0), return NGX_ERROR, log,
255 "ngx_select_process_events: " 210 "ngx_select_process_events: "
256 "select returns no events without timeout"); 211 "select returns no events without timeout");
257 } 212 }
258 213
259 ngx_log_debug(log, "ngx_select_process_events: " 214 ngx_log_debug(log, "ngx_select_process_events: "
266 /* void */) 221 /* void */)
267 { 222 {
268 delta -= ev->timer_delta; 223 delta -= ev->timer_delta;
269 nx = ev->timer_next; 224 nx = ev->timer_next;
270 ngx_del_timer(ev); 225 ngx_del_timer(ev);
271 #if 1
272 ev->timedout = 1; 226 ev->timedout = 1;
273 if (ev->event_handler(ev) == -1) 227 if (ev->event_handler(ev) == -1)
274 ev->close_handler(ev); 228 ev->close_handler(ev);
275 #else
276 if (ev->timer_handler(ev) == -1)
277 ev->close_handler(ev);
278 #endif
279 ev = nx; 229 ev = nx;
280 } 230 }
281 231
282 } else { 232 } else {
283 timer_queue.timer_next->timer_delta -= delta; 233 timer_queue.timer_next->timer_delta -= delta;
284 } 234 }
285 } 235 }
286 236
287 for (ev = event_queue.next; ev != &event_queue; ev = ev->next) { 237 for (ev = event_queue.next; ev != &event_queue; ev = ev->next) {
288 cn = (ngx_connection_t *) ev->data; 238 c = (ngx_connection_t *) ev->data;
289 found = 0; 239 found = 0;
290 240
291 if (ev->write) { 241 if (ev->write) {
292 if (FD_ISSET(cn->fd, &work_write_fds)) { 242 if (FD_ISSET(c->fd, &work_write_fd_set)) {
293 ngx_log_debug(log, "ngx_select_process_events: write %d" _ 243 ngx_log_debug(log, "ngx_select_process_events: write %d" _
294 cn->fd); 244 c->fd);
295 found = 1; 245 found = 1;
296 } 246 }
297 247
298 } else { 248 } else {
299 if (FD_ISSET(cn->fd, &work_read_fds)) { 249 if (FD_ISSET(c->fd, &work_read_fd_set)) {
300 ngx_log_debug(log, "ngx_select_process_events: read %d" _ 250 ngx_log_debug(log, "ngx_select_process_events: read %d" _
301 cn->fd); 251 c->fd);
302 found = 1; 252 found = 1;
303 } 253 }
304 } 254 }
305 255
306 if (found) { 256 if (found) {
307 ev->ready = 1; 257 ev->ready = 1;
258
259 if (ev->oneshot) {
260 ngx_del_timer(ev);
261 if (ev->write)
262 ngx_select_del_event(ev, NGX_WRITE_EVENT);
263 else
264 ngx_select_del_event(ev, NGX_READ_EVENT);
265 }
266
308 if (ev->event_handler(ev) == -1) 267 if (ev->event_handler(ev) == -1)
309 ev->close_handler(ev); 268 ev->close_handler(ev);
310 269
311 ready--; 270 ready--;
312 } 271 }
313 272
314 } 273 }
315 274
316 ngx_assert((ready == 0), return 0, log, 275 ngx_assert((ready == 0), /* void */ ; , log,
317 "ngx_select_process_events: ready != events"); 276 "ngx_select_process_events: ready != events");
318 277
319 return 0; 278 return NGX_OK;
320 } 279 }
321 280
322 static void ngx_add_timer_core(ngx_event_t *ev, u_int timer) 281 void ngx_select_add_timer(ngx_event_t *ev, ngx_msec_t timer)
323 { 282 {
324 ngx_event_t *e; 283 ngx_event_t *e;
325 284
326 for (e = timer_queue.timer_next; 285 for (e = timer_queue.timer_next;
327 e != &timer_queue && timer > e->timer_delta; 286 e != &timer_queue && timer > e->timer_delta;
334 ev->timer_prev = e->timer_prev; 293 ev->timer_prev = e->timer_prev;
335 294
336 e->timer_prev->timer_next = ev; 295 e->timer_prev->timer_next = ev;
337 e->timer_prev = ev; 296 e->timer_prev = ev;
338 } 297 }
339
340 #if 0
341 static void ngx_inline ngx_del_timer(ngx_event_t *ev)
342 {
343 if (ev->timer_prev)
344 ev->timer_prev->timer_next = ev->timer_next;
345
346 if (ev->timer_next) {
347 ev->timer_next->timer_prev = ev->timer_prev;
348 ev->timer_next = NULL;
349 }
350
351 if (ev->timer_prev)
352 ev->timer_prev = NULL;
353 }
354 #endif