Mercurial > hg > nginx
comparison src/event/modules/ngx_devpoll_module.c @ 92:19cc647ecd91
nginx-0.0.1-2003-05-20-19:37:55 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 20 May 2003 15:37:55 +0000 |
parents | e43f406e4525 |
children | 738fe44c70d5 |
comparison
equal
deleted
inserted
replaced
91:637625a2acdb | 92:19cc647ecd91 |
---|---|
1 | |
1 /* | 2 /* |
2 * Copyright (C) 2002 Igor Sysoev, http://sysoev.ru | 3 * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru |
3 */ | 4 */ |
4 | 5 |
5 | 6 |
6 #include <ngx_config.h> | 7 #include <ngx_config.h> |
7 #include <ngx_core.h> | 8 #include <ngx_core.h> |
8 #include <ngx_types.h> | |
9 #include <ngx_log.h> | |
10 #include <ngx_connection.h> | 9 #include <ngx_connection.h> |
11 #include <ngx_event.h> | 10 #include <ngx_event.h> |
12 #include <ngx_event_timer.h> | 11 |
13 #include <ngx_devpoll_module.h> | 12 |
14 | 13 #if (TEST_DEVPOLL) |
15 #if (USE_DEVPOLL) && !(HAVE_DEVPOLL) | 14 |
16 #error "/dev/poll is not supported on this platform" | 15 /* Solaris declarations */ |
17 #endif | 16 |
18 | 17 #define POLLREMOVE 0x0800 |
18 #define DP_POLL 0xD001 | |
19 | |
20 struct dvpoll { | |
21 struct pollfd *dp_fds; | |
22 int dp_nfds; | |
23 int dp_timeout; | |
24 }; | |
25 | |
26 #endif | |
27 | |
28 | |
29 typedef struct { | |
30 int changes; | |
31 int events; | |
32 } ngx_devpoll_conf_t; | |
33 | |
34 | |
35 static int ngx_devpoll_init(ngx_log_t *log); | |
36 static void ngx_devpoll_done(ngx_log_t *log); | |
37 static int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags); | |
38 static int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags); | |
19 static int ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags); | 39 static int ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags); |
40 static int ngx_devpoll_process_events(ngx_log_t *log); | |
41 | |
42 static void *ngx_devpoll_create_conf(ngx_pool_t *pool); | |
43 static char *ngx_devpoll_init_conf(ngx_pool_t *pool, void *conf); | |
20 | 44 |
21 /* STUB */ | 45 /* STUB */ |
22 #define DEVPOLL_NCHANGES 512 | 46 #define DEVPOLL_NCHANGES 512 |
23 #define DEVPOLL_NEVENTS 512 | 47 #define DEVPOLL_NEVENTS 512 |
24 | 48 |
25 /* should be per-thread */ | |
26 static int dp; | 49 static int dp; |
27 static struct pollfd *change_list, *event_list; | 50 static struct pollfd *change_list, *event_list; |
28 static unsigned int nchanges; | 51 static u_int nchanges, max_changes; |
29 static int nevents; | 52 static int nevents; |
30 | 53 |
31 static ngx_event_t **change_index; | 54 static ngx_event_t **change_index; |
32 | 55 |
33 static ngx_event_t *timer_queue; | 56 |
34 /* */ | 57 static ngx_str_t devpoll_name = ngx_string("/dev/poll"); |
35 | 58 |
36 | 59 static ngx_command_t ngx_devpoll_commands[] = { |
37 int ngx_devpoll_init(int max_connections, ngx_log_t *log) | 60 |
38 { | 61 {ngx_string("devpoll_changes"), |
39 int change_size, event_size; | 62 NGX_EVENT_CONF|NGX_CONF_TAKE1, |
40 | 63 ngx_conf_set_num_slot, |
41 nevents = DEVPOLL_NEVENTS; | 64 0, |
65 offsetof(ngx_devpoll_conf_t, changes), | |
66 NULL}, | |
67 | |
68 {ngx_string("devpoll_events"), | |
69 NGX_EVENT_CONF|NGX_CONF_TAKE1, | |
70 ngx_conf_set_num_slot, | |
71 0, | |
72 offsetof(ngx_devpoll_conf_t, events), | |
73 NULL}, | |
74 | |
75 {ngx_string(""), 0, NULL, 0, 0, NULL} | |
76 }; | |
77 | |
78 | |
79 ngx_event_module_t ngx_devpoll_module_ctx = { | |
80 NGX_EVENT_MODULE, | |
81 &devpoll_name, | |
82 ngx_devpoll_create_conf, /* create configuration */ | |
83 ngx_devpoll_init_conf, /* init configuration */ | |
84 | |
85 { | |
86 ngx_devpoll_add_event, /* add an event */ | |
87 ngx_devpoll_del_event, /* delete an event */ | |
88 ngx_devpoll_add_event, /* enable an event */ | |
89 ngx_devpoll_del_event, /* disable an event */ | |
90 NULL, /* add an connection */ | |
91 NULL, /* delete an connection */ | |
92 ngx_devpoll_process_events, /* process the events */ | |
93 ngx_devpoll_init, /* init the events */ | |
94 ngx_devpoll_done, /* done the events */ | |
95 } | |
96 | |
97 }; | |
98 | |
99 ngx_module_t ngx_devpoll_module = { | |
100 &ngx_devpoll_module_ctx, /* module context */ | |
101 0, /* module index */ | |
102 ngx_devpoll_commands, /* module directives */ | |
103 NGX_EVENT_MODULE_TYPE, /* module type */ | |
104 NULL /* init module */ | |
105 }; | |
106 | |
107 | |
108 static int ngx_devpoll_init(ngx_log_t *log) | |
109 { | |
110 ngx_devpoll_conf_t *dpcf; | |
111 | |
112 dpcf = ngx_event_get_conf(ngx_devpoll_module_ctx); | |
113 | |
114 ngx_log_debug(log, "CH: %d" _ dpcf->changes); | |
115 ngx_log_debug(log, "EV: %d" _ dpcf->events); | |
116 | |
117 max_changes = dpcf->changes; | |
118 nevents = dpcf->events; | |
42 nchanges = 0; | 119 nchanges = 0; |
43 change_size = sizeof(struct pollfd) * DEVPOLL_NCHANGES; | |
44 event_size = sizeof(struct pollfd) * DEVPOLL_NEVENTS; | |
45 | 120 |
46 dp = open("/dev/poll", O_RDWR); | 121 dp = open("/dev/poll", O_RDWR); |
47 | 122 |
48 if (dp == -1) { | 123 if (dp == -1) { |
49 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "open(/dev/poll) failed"); | 124 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "open(/dev/poll) failed"); |
50 return NGX_ERROR; | 125 return NGX_ERROR; |
51 } | 126 } |
52 | 127 |
53 ngx_test_null(change_list, ngx_alloc(change_size, log), NGX_ERROR); | 128 ngx_test_null(change_list, |
54 ngx_test_null(event_list, ngx_alloc(event_size, log), NGX_ERROR); | 129 ngx_alloc(sizeof(struct pollfd) * dpcf->changes, log), |
130 NGX_ERROR); | |
131 | |
132 ngx_test_null(event_list, | |
133 ngx_alloc(sizeof(struct pollfd) * dpcf->events, log), | |
134 NGX_ERROR); | |
135 | |
55 ngx_test_null(change_index, | 136 ngx_test_null(change_index, |
56 ngx_alloc(sizeof(ngx_event_t *) * DEVPOLL_NCHANGES, log), | 137 ngx_alloc(sizeof(ngx_event_t *) * dpcf->changes, log), |
57 NGX_ERROR); | 138 NGX_ERROR); |
58 | 139 |
59 timer_queue = ngx_event_init_timer(log); | 140 if (ngx_event_timer_init(log) == NGX_ERROR) { |
60 if (timer_queue == NULL) { | |
61 return NGX_ERROR; | 141 return NGX_ERROR; |
62 } | 142 } |
63 | 143 |
64 #if !(USE_DEVPOLL) | 144 ngx_event_actions = ngx_devpoll_module_ctx.actions; |
65 ngx_event_actions.add = ngx_devpoll_add_event; | 145 ngx_event_flags = NGX_HAVE_LEVEL_EVENT|NGX_USE_LEVEL_EVENT; |
66 ngx_event_actions.del = ngx_devpoll_del_event; | |
67 ngx_event_actions.timer = ngx_event_add_timer; | |
68 ngx_event_actions.process = ngx_devpoll_process_events; | |
69 #endif | |
70 | 146 |
71 return NGX_OK; | 147 return NGX_OK; |
72 } | 148 } |
73 | 149 |
74 | 150 |
75 int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags) | 151 static void ngx_devpoll_done(ngx_log_t *log) |
152 { | |
153 if (close(dp) == -1) { | |
154 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close(/dev/poll) failed"); | |
155 } | |
156 | |
157 ngx_event_timer_done(log); | |
158 | |
159 ngx_free(change_list); | |
160 ngx_free(event_list); | |
161 ngx_free(change_index); | |
162 | |
163 } | |
164 | |
165 | |
166 static int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags) | |
76 { | 167 { |
77 #if (NGX_DEBUG_EVENT) | 168 #if (NGX_DEBUG_EVENT) |
78 ngx_connection_t *c = (ngx_connection_t *) ev->data; | 169 ngx_connection_t *c = (ngx_connection_t *) ev->data; |
79 #endif | 170 #endif |
80 | 171 |
92 c = (ngx_connection_t *) ev->data; | 183 c = (ngx_connection_t *) ev->data; |
93 ngx_log_debug(ev->log, "add event: %d:%d" _ c->fd _ event); | 184 ngx_log_debug(ev->log, "add event: %d:%d" _ c->fd _ event); |
94 #endif | 185 #endif |
95 | 186 |
96 ev->active = 1; | 187 ev->active = 1; |
97 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; | |
98 | |
99 return ngx_devpoll_set_event(ev, event, 0); | 188 return ngx_devpoll_set_event(ev, event, 0); |
100 } | 189 } |
101 | 190 |
102 | 191 |
103 int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags) | 192 static int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags) |
104 { | 193 { |
105 ngx_event_t *e; | 194 ngx_event_t *e; |
106 | 195 |
107 #if (NGX_DEBUG_EVENT) | 196 #if (NGX_DEBUG_EVENT) |
108 ngx_connection_t *c = (ngx_connection_t *) ev->data; | 197 ngx_connection_t *c = (ngx_connection_t *) ev->data; |
141 static int ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags) | 230 static int ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags) |
142 { | 231 { |
143 int n; | 232 int n; |
144 ngx_connection_t *c; | 233 ngx_connection_t *c; |
145 | 234 |
146 c = (ngx_connection_t *) ev->data; | 235 c = ev->data; |
147 | 236 |
148 #if (NGX_DEBUG_EVENT) | 237 #if (NGX_DEBUG_EVENT) |
149 ngx_log_debug(ev->log, "devpoll fd:%d event:%d flush:%d" _ | 238 ngx_log_debug(ev->log, "devpoll fd:%d event:%d flush:%d" _ |
150 c->fd _ event _ flags); | 239 c->fd _ event _ flags); |
151 #endif | 240 #endif |
152 | 241 |
153 if (nchanges >= DEVPOLL_NCHANGES) { | 242 if (nchanges >= max_changes) { |
154 ngx_log_error(NGX_LOG_WARN, ev->log, 0, | 243 ngx_log_error(NGX_LOG_WARN, ev->log, 0, |
155 "/dev/pool change list is filled up"); | 244 "/dev/pool change list is filled up"); |
156 | 245 |
157 n = nchanges * sizeof(struct pollfd); | 246 n = nchanges * sizeof(struct pollfd); |
158 if (write(dp, change_list, n) != n) { | 247 if (write(dp, change_list, n) != n) { |
264 if (!c->read->active) { | 353 if (!c->read->active) { |
265 continue; | 354 continue; |
266 } | 355 } |
267 | 356 |
268 c->read->ready = 1; | 357 c->read->ready = 1; |
269 | 358 c->read->event_handler(c->read); |
270 if (c->read->oneshot) { | |
271 ngx_del_timer(c->read); | |
272 ngx_devpoll_del_event(c->read, NGX_READ_EVENT, 0); | |
273 } | |
274 | |
275 if (c->read->event_handler(c->read) == NGX_ERROR) { | |
276 c->read->close_handler(c->read); | |
277 } | |
278 } | 359 } |
279 | 360 |
280 if (event_list[i].revents & POLLOUT) { | 361 if (event_list[i].revents & POLLOUT) { |
281 if (!c->write->active) { | 362 if (!c->write->active) { |
282 continue; | 363 continue; |
283 } | 364 } |
284 | 365 |
285 c->write->ready = 1; | 366 c->write->ready = 1; |
286 | 367 c->write->event_handler(c->write); |
287 if (c->write->oneshot) { | |
288 ngx_del_timer(c->write); | |
289 ngx_devpoll_del_event(c->write, NGX_WRITE_EVENT, 0); | |
290 } | |
291 | |
292 if (c->write->event_handler(c->write) == NGX_ERROR) { | |
293 c->write->close_handler(c->write); | |
294 } | |
295 } | 368 } |
296 | 369 |
297 if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { | 370 if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { |
298 err = 0; | 371 err = 0; |
299 if (event_list[i].revents & POLLNVAL) { | 372 if (event_list[i].revents & POLLNVAL) { |
306 } | 379 } |
307 } | 380 } |
308 | 381 |
309 return NGX_OK; | 382 return NGX_OK; |
310 } | 383 } |
384 | |
385 | |
386 static void *ngx_devpoll_create_conf(ngx_pool_t *pool) | |
387 { | |
388 ngx_devpoll_conf_t *dpcf; | |
389 | |
390 ngx_test_null(dpcf, ngx_palloc(pool, sizeof(ngx_devpoll_conf_t)), | |
391 NGX_CONF_ERROR); | |
392 | |
393 dpcf->changes = NGX_CONF_UNSET; | |
394 dpcf->events = NGX_CONF_UNSET; | |
395 | |
396 return dpcf; | |
397 } | |
398 | |
399 | |
400 static char *ngx_devpoll_init_conf(ngx_pool_t *pool, void *conf) | |
401 { | |
402 ngx_devpoll_conf_t *dpcf = conf; | |
403 | |
404 ngx_conf_init_value(dpcf->changes, 512); | |
405 ngx_conf_init_value(dpcf->events, 512); | |
406 | |
407 return NGX_CONF_OK; | |
408 } |