comparison src/event/modules/ngx_select_module.c @ 0:4eff17414a43

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