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 }