comparison src/event/modules/ngx_devpoll_module.c @ 39:83fa61cd3d2f

nginx-0.0.1-2002-12-24-20:30:59 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 24 Dec 2002 17:30:59 +0000
parents c14d7232b11f
children d5d4f3bba6f0
comparison
equal deleted inserted replaced
38:2ffaa35fba42 39:83fa61cd3d2f
14 #if (USE_DEVPOLL) && !(HAVE_DEVPOLL) 14 #if (USE_DEVPOLL) && !(HAVE_DEVPOLL)
15 #error "/dev/poll is not supported on this platform" 15 #error "/dev/poll is not supported on this platform"
16 #endif 16 #endif
17 17
18 18
19 /* STUB */
20 #define DEVPOLL_NCHANGES 512
21 #define DEVPOLL_NEVENTS 512
22
19 /* should be per-thread */ 23 /* should be per-thread */
20 static int dp; 24 static int dp;
21 static struct pollfd *change_list, *event_list; 25 static struct pollfd *change_list, *event_list;
22 static int nchanges, nevents; 26 static unsigned int nchanges;
27 static int nevents;
28
29 static ngx_event_t **change_index;
23 30
24 static ngx_event_t timer_queue; 31 static ngx_event_t timer_queue;
25 /* */ 32 /* */
26 33
27 34
28 int ngx_devpoll_init(int max_connections, ngx_log_t *log) 35 int ngx_devpoll_init(int max_connections, ngx_log_t *log)
29 { 36 {
30 int size; 37 int change_size, event_size;
31 38
32 size = sizeof(struct pollfd) * 512; 39 nevents = DEVPOLL_NEVENTS;
33 nchanges = 0; 40 nchanges = 0;
34 nevents = 512; 41 change_size = sizeof(struct pollfd) * DEVPOLL_NCHANGES;
42 event_size = sizeof(struct pollfd) * DEVPOLL_NEVENTS;
35 43
36 dp = open("/dev/poll", O_RDWR); 44 dp = open("/dev/poll", O_RDWR);
37 45
38 if (dp == -1) { 46 if (dp == -1) {
39 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "open(/dev/poll) failed"); 47 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "open(/dev/poll) failed");
40 return NGX_ERROR; 48 return NGX_ERROR;
41 } 49 }
42 50
43 ngx_test_null(change_list, ngx_alloc(size, log), NGX_ERROR); 51 ngx_test_null(change_list, ngx_alloc(change_size, log), NGX_ERROR);
44 ngx_test_null(event_list, ngx_alloc(size, log), NGX_ERROR); 52 ngx_test_null(event_list, ngx_alloc(event_size, log), NGX_ERROR);
45 ngx_test_null(event_index, ngx_alloc(sizeof(ngx_event_t *) * nevents, log), 53 ngx_test_null(change_index,
54 ngx_alloc(sizeof(ngx_event_t *) * DEVPOLL_NCHANGES, log),
46 NGX_ERROR); 55 NGX_ERROR);
47 56
48 timer_queue.timer_prev = &timer_queue; 57 timer_queue.timer_prev = &timer_queue;
49 timer_queue.timer_next = &timer_queue; 58 timer_queue.timer_next = &timer_queue;
50 59
57 66
58 return NGX_OK; 67 return NGX_OK;
59 } 68 }
60 69
61 70
62 /* NOT READY */
63
64 int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags) 71 int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags)
65 { 72 {
66 ngx_event_t *e; 73 #if (NGX_DEBUG_EVENT)
67 ngx_connection_t *c; 74 ngx_connection_t *c = (ngx_connection_t *) ev->data;
68 75 #endif
76
77 #if (NGX_READ_EVENT != POLLIN)
78 if (event == NGX_READ_EVENT) {
79 event = POLLOUT;
80 #if (NGX_WRITE_EVENT != POLLOUT)
81 } else {
82 event = POLLIN;
83 #endif
84 }
85 #endif
86
87 #if (NGX_DEBUG_EVENT)
69 c = (ngx_connection_t *) ev->data; 88 c = (ngx_connection_t *) ev->data;
70 89 ngx_log_debug(ev->log, "add event: %d:%d" _ c->fd _ event);
90 #endif
91
92 ev->active = 1;
71 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; 93 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
94
95 return ngx_devpoll_set_event(ev, event, 0);
96 }
97
98
99 int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
100 {
101 ngx_event_t *e;
102
103 #if (NGX_DEBUG_EVENT)
104 ngx_connection_t *c = (ngx_connection_t *) ev->data;
105 ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event);
106 #endif
107
108 if (ngx_devpoll_set_event(ev, POLLREMOVE, flags) == NGX_ERROR) {
109 return NGX_ERROR;
110 }
111
112 ev->active = 0;
113
114 if (flags & NGX_CLOSE_EVENT) {
115 return NGX_OK;
116 }
72 117
73 if (event == NGX_READ_EVENT) { 118 if (event == NGX_READ_EVENT) {
74 e = c->write; 119 e = c->write;
75 #if (NGX_READ_EVENT != POLLIN) 120 event = POLLOUT;
76 event = POLLIN;
77 #endif
78 121
79 } else { 122 } else {
80 e = c->read; 123 e = c->read;
81 #if (NGX_WRITE_EVENT != POLLOUT) 124 event = POLLIN;
82 event = POLLOUT; 125 }
83 #endif 126
84 } 127 if (e) {
85 128 return ngx_devpoll_set_event(e, event, 0);
86 ngx_log_debug(ev->log, "poll fd:%d event:%d" _ c->fd _ event); 129 }
87 130
88 if (e == NULL || e->index == NGX_INVALID_INDEX) { 131 return NGX_OK;
89 event_list[nevents].fd = c->fd; 132 }
90 event_list[nevents].events = event; 133
91 event_list[nevents].revents = 0; 134
92 135 int ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags)
93 event_index[nevents] = ev;
94 ev->index = nevents;
95 nevents++;
96
97 } else {
98 event_list[e->index].events |= event;
99 ev->index = e->index;
100 }
101
102 return ngx_devpoll_set_event(ev, event, EV_ADD | flags);
103 }
104
105 /* NOT READY */
106
107 int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
108 {
109 ngx_event_t *e;
110
111 if (nchanges > 0 && ev->index < nchanges
112 && change_list[ev->index].udata == ev)
113 {
114 ngx_connection_t *cn = (ngx_connection_t *) ev->data;
115 ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _
116 cn->fd _ event);
117
118 if (ev->index < --nchanges) {
119 e = (ngx_event_t *) change_list[nchanges].udata;
120 change_list[ev->index] = change_list[nchanges];
121 e->index = ev->index;
122 }
123
124 return NGX_OK;
125 }
126
127 if (flags & NGX_CLOSE_EVENT)
128 return NGX_OK;
129
130 return ngx_devpoll_set_event(ev, POLLREMOVE);
131 }
132
133 /* NOT READY */
134
135 int ngx_devpoll_set_event(ngx_event_t *ev, int event)
136 { 136 {
137 int n; 137 int n;
138 ngx_connection_t *c; 138 ngx_connection_t *c;
139 139
140 c = (ngx_connection_t *) ev->data; 140 c = (ngx_connection_t *) ev->data;
141 141
142 ngx_log_debug(ev->log, "devpoll fd:%d event:%d" _ c->fd _ event); 142 #if (NGX_DEBUG_EVENT)
143 143 ngx_log_debug(ev->log, "devpoll fd:%d event:%d flush:%d" _
144 if (nchanges >= nevents) { 144 c->fd _ event _ flags);
145 #endif
146
147 if (nchanges >= DEVPOLL_NCHANGES) {
145 ngx_log_error(NGX_LOG_WARN, ev->log, 0, 148 ngx_log_error(NGX_LOG_WARN, ev->log, 0,
146 "/dev/pool change list is filled up"); 149 "/dev/pool change list is filled up");
147 150
148 n = nchanges * sizeof(struct pollfd); 151 n = nchanges * sizeof(struct pollfd);
149 if (write(dp, change_list, n) != n) { 152 if (write(dp, change_list, n) != n) {
150 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, 153 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
151 "write(/dev/poll) failed"); 154 "write(/dev/poll) failed");
152 return NGX_ERROR; 155 return NGX_ERROR;
153 } 156 }
154 157
155 nchanges = 0; 158 nchanges = 0;
156 } 159 }
157 160
158 event_list[nchanges].fd = c->fd; 161 change_list[nchanges].fd = c->fd;
159 event_list[nchanges].events = event; 162 change_list[nchanges].events = event;
160 event_list[nchanges].revents = 0; 163 change_list[nchanges].revents = 0;
161 164
162 event_index[nchanges] = ev; 165 change_index[nchanges] = ev;
163 ev->index = nchanges; 166 ev->index = nchanges;
164 167
165 /*
166 if (flags == EV_ADD)
167 ev->index = nchanges;
168 */
169
170 nchanges++; 168 nchanges++;
171 169
170 if (flags & NGX_CLOSE_EVENT) {
171 n = nchanges * sizeof(struct pollfd);
172 if (write(dp, change_list, n) != n) {
173 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
174 "write(/dev/poll) failed");
175 return NGX_ERROR;
176 }
177
178 nchanges = 0;
179 }
180
172 return NGX_OK; 181 return NGX_OK;
173 } 182 }
174 183
175 184
176 int ngx_devpoll_process_events(ngx_log_t *log) 185 int ngx_devpoll_process_events(ngx_log_t *log)
177 { 186 {
178 int events, i; 187 int events, n, i;
179 u_int timer, delta; 188 u_int timer, delta;
180 ngx_event_t *ev; 189 ngx_err_t err;
181 struct dvpoll dvpoll; 190 ngx_event_t *ev;
182 struct timeval tv; 191 ngx_connection_t *c;
192 struct dvpoll dvpoll;
193 struct timeval tv;
183 194
184 if (timer_queue.timer_next != &timer_queue) { 195 if (timer_queue.timer_next != &timer_queue) {
185 timer = timer_queue.timer_next->timer_delta; 196 timer = timer_queue.timer_next->timer_delta;
186 #if 1
187 gettimeofday(&tv, NULL); 197 gettimeofday(&tv, NULL);
188 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; 198 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000;
189 #else
190 delta = ngx_msec();
191 #endif
192 199
193 } else { 200 } else {
194 timer = INFTIM; 201 timer = INFTIM;
195 delta = 0; 202 delta = 0;
196 } 203 }
197 204
205 #if (NGX_DEBUG_EVENT)
198 ngx_log_debug(log, "devpoll timer: %d" _ timer); 206 ngx_log_debug(log, "devpoll timer: %d" _ timer);
207 #endif
199 208
200 n = nchanges * sizeof(struct pollfd); 209 n = nchanges * sizeof(struct pollfd);
201 if (write(dp, change_list, n) != n) { 210 if (write(dp, change_list, n) != n) {
202 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "write(/dev/poll) failed"); 211 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "write(/dev/poll) failed");
203 return NGX_ERROR; 212 return NGX_ERROR;
214 } 223 }
215 224
216 nchanges = 0; 225 nchanges = 0;
217 226
218 if (timer != INFTIM) { 227 if (timer != INFTIM) {
219 #if 1
220 gettimeofday(&tv, NULL); 228 gettimeofday(&tv, NULL);
221 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; 229 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
222 #else
223 delta = ngx_msec() - delta;
224 #endif
225 230
226 } else { 231 } else {
227 ngx_assert((events != 0), return NGX_ERROR, log, 232 if (events == 0) {
228 "ioctl(DP_POLL) returns no events without timeout"); 233 ngx_log_error(NGX_LOG_ALERT, log, 0,
229 } 234 "ioctl(DP_POLL) returns no events without timeout");
230 235 return NGX_ERROR;
236 }
237 }
238
239 #if (NGX_DEBUG_EVENT)
231 ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ delta); 240 ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ delta);
232 241 #endif
233 if (timer != INFTIM) {
234 if (delta >= timer) {
235 for ( ;; ) {
236 ev = timer_queue.timer_next;
237
238 if (ev == &timer_queue || delta < ev->timer_delta)
239 break;
240
241 delta -= ev->timer_delta;
242 ngx_del_timer(ev);
243 ev->timedout = 1;
244 if (ev->event_handler(ev) == NGX_ERROR)
245 ev->close_handler(ev);
246 }
247
248 } else {
249 timer_queue.timer_next->timer_delta -= delta;
250 }
251 }
252 242
253 for (i = 0; i < events; i++) { 243 for (i = 0; i < events; i++) {
254 244
245 #if (NGX_DEBUG_EVENT)
255 ngx_log_debug(log, "devpoll: %d: ev:%d rev:%d" _ 246 ngx_log_debug(log, "devpoll: %d: ev:%d rev:%d" _
256 event_list[i].fd _ 247 event_list[i].fd _
257 event_list[i].events _ event_list[i].revents); 248 event_list[i].events _ event_list[i].revents);
258 249 #endif
250
251 c = &ngx_connections[event_list[i].fd];
259 252
260 if (event_list[i].revents & POLLIN) { 253 if (event_list[i].revents & POLLIN) {
254 if (!c->read->active) {
255 continue;
256 }
257
261 c->read->ready = 1; 258 c->read->ready = 1;
262 259
263 if (c->read->oneshot) { 260 if (c->read->oneshot) {
264 ngx_del_timer(c->read); 261 ngx_del_timer(c->read);
265 ngx_select_del_event(c->read, NGX_READ_EVENT, 0); 262 ngx_devpoll_del_event(c->read, NGX_READ_EVENT, 0);
266 } 263 }
267 264
268 if (c->read->event_handler(c->read) == NGX_ERROR) { 265 if (c->read->event_handler(c->read) == NGX_ERROR) {
269 c->read->close_handler(c->read); 266 c->read->close_handler(c->read);
270 } 267 }
271 } 268 }
272 269
273 if (event_list[i].revents & POLLOUT) { 270 if (event_list[i].revents & POLLOUT) {
271 if (!c->write->active) {
272 continue;
273 }
274
274 c->write->ready = 1; 275 c->write->ready = 1;
275 276
276 if (c->write->oneshot) { 277 if (c->write->oneshot) {
277 ngx_del_timer(c->write); 278 ngx_del_timer(c->write);
278 ngx_select_del_event(c->write, NGX_WRITE_EVENT, 0); 279 ngx_devpoll_del_event(c->write, NGX_WRITE_EVENT, 0);
279 } 280 }
280 281
281 if (c->write->event_handler(c->write) == NGX_ERROR) { 282 if (c->write->event_handler(c->write) == NGX_ERROR) {
282 c->write->close_handler(c->write); 283 c->write->close_handler(c->write);
283 } 284 }
284 } 285 }
285 286
286 if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { 287 if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) {
287 ngx_log_error(NGX_LOG_ERR, log, ngx_errno, 288 err = 0;
289 if (event_list[i].revents & POLLNVAL) {
290 err = EBADF;
291 }
292
293 ngx_log_error(NGX_LOG_ERR, log, err,
288 "ioctl(DP_POLL) error on %d:%d", 294 "ioctl(DP_POLL) error on %d:%d",
289 event_list[i].fd, event_list[i].revents); 295 event_list[i].fd, event_list[i].revents);
290 } 296 }
291 } 297 }
292 298
299 if (timer != INFTIM && timer_queue.timer_next != &timer_queue) {
300 if (delta >= timer_queue.timer_next->timer_delta) {
301 for ( ;; ) {
302 ev = timer_queue.timer_next;
303
304 if (ev == &timer_queue || delta < ev->timer_delta) {
305 break;
306 }
307
308 delta -= ev->timer_delta;
309
310 ngx_del_timer(ev);
311 ev->timedout = 1;
312 if (ev->event_handler(ev) == NGX_ERROR) {
313 ev->close_handler(ev);
314 }
315 }
316
317 } else {
318 timer_queue.timer_next->timer_delta -= delta;
319 }
320 }
321
293 return NGX_OK; 322 return NGX_OK;
294 } 323 }
295 324
296 325
297 void ngx_devpoll_add_timer(ngx_event_t *ev, ngx_msec_t timer) 326 void ngx_devpoll_add_timer(ngx_event_t *ev, ngx_msec_t timer)
298 { 327 {
299 ngx_event_t *e; 328 ngx_event_t *e;
300 329
301 ngx_log_debug(ev->log, "set timer: %d" _ timer); 330 #if (NGX_DEBUG_EVENT)
302 331 ngx_connection_t *c = (ngx_connection_t *) ev->data;
303 ngx_assert((!ev->timer_next && !ev->timer_prev), return, ev->log, 332 ngx_log_debug(ev->log, "set timer: %d:%d" _ c->fd _ timer);
304 "timer already set"); 333 #endif
334
335 if (ev->timer_next || ev->timer_prev) {
336 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "timer already set");
337 return;
338 }
305 339
306 for (e = timer_queue.timer_next; 340 for (e = timer_queue.timer_next;
307 e != &timer_queue && timer > e->timer_delta; 341 e != &timer_queue && timer > e->timer_delta;
308 e = e->timer_next) 342 e = e->timer_next)
343 {
309 timer -= e->timer_delta; 344 timer -= e->timer_delta;
345 }
310 346
311 ev->timer_delta = timer; 347 ev->timer_delta = timer;
312 348
313 ev->timer_next = e; 349 ev->timer_next = e;
314 ev->timer_prev = e->timer_prev; 350 ev->timer_prev = e->timer_prev;