comparison src/event/modules/ngx_poll_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 2ffaa35fba42
children b288069a8696
comparison
equal deleted inserted replaced
38:2ffaa35fba42 39:83fa61cd3d2f
10 #include <ngx_poll_module.h> 10 #include <ngx_poll_module.h>
11 11
12 12
13 /* should be per-thread */ 13 /* should be per-thread */
14 static struct pollfd *event_list; 14 static struct pollfd *event_list;
15 static int nevents; 15 static unsigned int nevents;
16 16
17 static ngx_event_t **event_index; 17 static ngx_event_t **event_index;
18 static ngx_event_t **ready_index;
18 static ngx_event_t timer_queue; 19 static ngx_event_t timer_queue;
19 /* */ 20 /* */
20 21
21 int ngx_poll_init(int max_connections, ngx_log_t *log) 22 int ngx_poll_init(int max_connections, ngx_log_t *log)
22 { 23 {
24 ngx_alloc(sizeof(struct pollfd) * max_connections, log), 25 ngx_alloc(sizeof(struct pollfd) * max_connections, log),
25 NGX_ERROR); 26 NGX_ERROR);
26 27
27 ngx_test_null(event_index, 28 ngx_test_null(event_index,
28 ngx_alloc(sizeof(ngx_event_t *) * max_connections, log), 29 ngx_alloc(sizeof(ngx_event_t *) * max_connections, log),
30 NGX_ERROR);
31
32 ngx_test_null(ready_index,
33 ngx_alloc(sizeof(ngx_event_t *) * 2 * max_connections, log),
29 NGX_ERROR); 34 NGX_ERROR);
30 35
31 nevents = 0; 36 nevents = 0;
32 37
33 timer_queue.timer_prev = &timer_queue; 38 timer_queue.timer_prev = &timer_queue;
41 return NGX_OK; 46 return NGX_OK;
42 } 47 }
43 48
44 int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags) 49 int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
45 { 50 {
46 ngx_event_t *e; 51 ngx_event_t *e;
47 ngx_connection_t *c; 52 ngx_connection_t *c;
48 53
49 c = (ngx_connection_t *) ev->data; 54 c = (ngx_connection_t *) ev->data;
50 55
56 ev->active = 1;
51 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; 57 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
52 58
53 if (event == NGX_READ_EVENT) { 59 if (event == NGX_READ_EVENT) {
54 e = c->write; 60 e = c->write;
55 #if (NGX_READ_EVENT != POLLIN) 61 #if (NGX_READ_EVENT != POLLIN)
61 #if (NGX_WRITE_EVENT != POLLOUT) 67 #if (NGX_WRITE_EVENT != POLLOUT)
62 event = POLLOUT; 68 event = POLLOUT;
63 #endif 69 #endif
64 } 70 }
65 71
66 ngx_log_debug(ev->log, "poll fd:%d event:%d" _ c->fd _ event); 72 #if (NGX_DEBUG_EVENT)
73 ngx_log_debug(ev->log, "add event: %d:%d" _ c->fd _ event);
74 #endif
67 75
68 if (e == NULL || e->index == NGX_INVALID_INDEX) { 76 if (e == NULL || e->index == NGX_INVALID_INDEX) {
69 event_list[nevents].fd = c->fd; 77 event_list[nevents].fd = c->fd;
70 event_list[nevents].events = event; 78 event_list[nevents].events = event;
71 event_list[nevents].revents = 0; 79 event_list[nevents].revents = 0;
82 return NGX_OK; 90 return NGX_OK;
83 } 91 }
84 92
85 int ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags) 93 int ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
86 { 94 {
87 ngx_event_t *e; 95 ngx_event_t *e;
88 ngx_connection_t *c; 96 ngx_connection_t *c;
89 97
90 c = (ngx_connection_t *) ev->data; 98 c = (ngx_connection_t *) ev->data;
91 99
92 if (ev->index == NGX_INVALID_INDEX) 100 if (ev->index == NGX_INVALID_INDEX) {
93 return NGX_OK; 101 return NGX_OK;
102 }
94 103
95 if (event == NGX_READ_EVENT) { 104 if (event == NGX_READ_EVENT) {
96 e = c->write; 105 e = c->write;
97 #if (NGX_READ_EVENT != POLLIN) 106 #if (NGX_READ_EVENT != POLLIN)
98 event = POLLIN; 107 event = POLLIN;
103 #if (NGX_WRITE_EVENT != POLLOUT) 112 #if (NGX_WRITE_EVENT != POLLOUT)
104 event = POLLOUT; 113 event = POLLOUT;
105 #endif 114 #endif
106 } 115 }
107 116
117 #if (NGX_DEBUG_EVENT)
108 ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event); 118 ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event);
119 #endif
109 120
110 if (e == NULL || e->index == NGX_INVALID_INDEX) { 121 if (e == NULL || e->index == NGX_INVALID_INDEX) {
111 if (ev->index < --nevents) { 122 if (ev->index < --nevents) {
112 event_list[ev->index] = event_list[nevents]; 123 event_list[ev->index] = event_list[nevents];
113 event_index[ev->index] = event_index[nevents]; 124 event_index[ev->index] = event_index[nevents];
116 127
117 } else { 128 } else {
118 event_list[e->index].events &= ~event; 129 event_list[e->index].events &= ~event;
119 } 130 }
120 131
132 ev->active = 0;
121 ev->index = NGX_INVALID_INDEX; 133 ev->index = NGX_INVALID_INDEX;
122 134
123 return NGX_OK; 135 return NGX_OK;
124 } 136 }
125 137
126 int ngx_poll_process_events(ngx_log_t *log) 138 int ngx_poll_process_events(ngx_log_t *log)
127 { 139 {
128 int i, ready, found; 140 int i, ready, nready, found;
129 u_int timer, delta; 141 u_int timer, delta;
130 ngx_err_t err; 142 ngx_err_t err;
131 ngx_event_t *ev; 143 ngx_event_t *ev;
132 ngx_connection_t *c; 144 ngx_connection_t *c;
133 145
138 } else { 150 } else {
139 timer = INFTIM; 151 timer = INFTIM;
140 delta = 0; 152 delta = 0;
141 } 153 }
142 154
143 #if 1 155 #if (NGX_DEBUG_EVENT)
144 /* DEBUG */
145 for (i = 0; i < nevents; i++) { 156 for (i = 0; i < nevents; i++) {
146 ngx_log_debug(log, "poll: %d, %d" _ 157 ngx_log_debug(log, "poll: %d, %d" _
147 event_list[i].fd _ event_list[i].events); 158 event_list[i].fd _ event_list[i].events);
148 } 159 }
149 #endif
150 160
151 ngx_log_debug(log, "poll timer: %d" _ timer); 161 ngx_log_debug(log, "poll timer: %d" _ timer);
162 #endif
152 163
153 if ((ready = poll(event_list, nevents, timer)) == -1) { 164 if ((ready = poll(event_list, nevents, timer)) == -1) {
154 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "poll() failed"); 165 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "poll() failed");
155 return NGX_ERROR; 166 return NGX_ERROR;
156 } 167 }
159 170
160 if (timer != INFTIM) { 171 if (timer != INFTIM) {
161 delta = ngx_msec() - delta; 172 delta = ngx_msec() - delta;
162 173
163 } else { 174 } else {
164 ngx_assert((ready != 0), return NGX_ERROR, log, 175 if (ready == 0) {
165 "poll() returns no events without timeout"); 176 ngx_log_error(NGX_LOG_ALERT, log, 0,
166 } 177 "poll() returns no events without timeout");
167 178 return NGX_ERROR;
179 }
180 }
181
182 #if (NGX_DEBUG_EVENT)
168 ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ delta); 183 ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ delta);
169 184 #endif
170 if (timer != INFTIM) { 185
171 if (delta >= timer) { 186 nready = 0;
187
188 for (i = 0; i < nevents && ready; i++) {
189 c = &ngx_connections[event_list[i].fd];
190
191 #if (NGX_DEBUG_EVENT)
192 ngx_log_debug(log, "poll: fd:%d, ev:%d, rev:%d" _
193 event_list[i].fd _
194 event_list[i].events _ event_list[i].revents);
195 #endif
196
197 found = 0;
198
199 if (event_list[i].revents & POLLIN) {
200 found = 1;
201 ready_index[nready++] = c->read;
202 }
203
204 if (event_list[i].revents & POLLOUT) {
205 found = 1;
206 ready_index[nready++] = c->write;
207 }
208
209 if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) {
210 found = 1;
211
212 err = 0;
213 if (event_list[i].revents & POLLNVAL) {
214 err = EBADF;
215 }
216
217 ngx_log_error(NGX_LOG_ERR, log, err,
218 "poll() error on %d:%d",
219 event_list[i].fd, event_list[i].revents);
220 }
221
222 if (found) {
223 ready--;
224 }
225 }
226
227 for (i = 0; i < nready; i++) {
228 ev = ready_index[i];
229
230 if (!ev->active) {
231 continue;
232 }
233
234 ev->ready = 1;
235
236 if (ev->oneshot) {
237 ngx_del_timer(ev);
238
239 if (ev->write) {
240 ngx_poll_del_event(ev, NGX_WRITE_EVENT, 0);
241 } else {
242 ngx_poll_del_event(ev, NGX_READ_EVENT, 0);
243 }
244 }
245
246 if (ev->event_handler(ev) == NGX_ERROR) {
247 ev->close_handler(ev);
248 }
249 }
250
251 if (ready != 0) {
252 ngx_log_error(NGX_LOG_ALERT, log, 0, "poll ready != events");
253 }
254
255 if (timer != INFTIM && timer_queue.timer_next != &timer_queue) {
256 if (delta >= timer_queue.timer_next->timer_delta) {
172 for ( ;; ) { 257 for ( ;; ) {
173 ev = timer_queue.timer_next; 258 ev = timer_queue.timer_next;
174 259
175 if (ev == &timer_queue || delta < ev->timer_delta) { 260 if (ev == &timer_queue || delta < ev->timer_delta) {
176 break; 261 break;
177 } 262 }
178 263
179 delta -= ev->timer_delta; 264 delta -= ev->timer_delta;
265
180 ngx_del_timer(ev); 266 ngx_del_timer(ev);
181 ev->timedout = 1; 267 ev->timedout = 1;
182
183 if (ev->event_handler(ev) == NGX_ERROR) { 268 if (ev->event_handler(ev) == NGX_ERROR) {
184 ev->close_handler(ev); 269 ev->close_handler(ev);
185 } 270 }
186 } 271 }
187 272
188 } else { 273 } else {
189 timer_queue.timer_next->timer_delta -= delta; 274 timer_queue.timer_next->timer_delta -= delta;
190 } 275 }
191 } 276 }
192 277
193 for (i = 0; i < nevents && ready; i++) {
194 c = &ngx_connections[event_list[i].fd];
195
196 ngx_log_debug(log, "poll: fd:%d, ev:%d, rev:%d" _
197 event_list[i].fd _
198 event_list[i].events _ event_list[i].revents);
199
200 found = 0;
201
202 if (event_list[i].revents & POLLIN) {
203 found = 1;
204 c->read->ready = 1;
205
206 if (c->read->oneshot) {
207 ngx_del_timer(c->read);
208 ngx_poll_del_event(c->read, NGX_READ_EVENT, 0);
209 }
210
211 if (c->read->event_handler(c->read) == NGX_ERROR) {
212 c->read->close_handler(c->read);
213 }
214 }
215
216 if (event_list[i].revents & POLLOUT) {
217 found = 1;
218 c->write->ready = 1;
219
220 if (c->write->oneshot) {
221 ngx_del_timer(c->write);
222 ngx_poll_del_event(c->write, NGX_WRITE_EVENT, 0);
223 }
224
225 if (c->write->event_handler(c->write) == NGX_ERROR) {
226 c->write->close_handler(c->write);
227 }
228 }
229
230 if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) {
231 found = 1;
232
233 err = 0;
234 if (event_list[i].revents & POLLNVAL) {
235 err = EBADF;
236 }
237
238 ngx_log_error(NGX_LOG_ERR, log, err,
239 "poll() error on %d:%d",
240 event_list[i].fd, event_list[i].revents);
241 }
242
243 if (found) {
244 ready--;
245 }
246 }
247
248 ngx_assert((ready == 0), /* void */ ; , log, "poll ready != nevents");
249
250 return NGX_OK; 278 return NGX_OK;
251 } 279 }
252 280
253 void ngx_poll_add_timer(ngx_event_t *ev, ngx_msec_t timer) 281 void ngx_poll_add_timer(ngx_event_t *ev, ngx_msec_t timer)
254 { 282 {
255 ngx_event_t *e; 283 ngx_event_t *e;
284
285 #if (NGX_DEBUG_EVENT)
286 ngx_connection_t *c = (ngx_connection_t *) ev->data;
287 ngx_log_debug(ev->log, "set timer: %d:%d" _ c->fd _ timer);
288 #endif
289
290 if (ev->timer_next || ev->timer_prev) {
291 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "timer already set");
292 return;
293 }
256 294
257 for (e = timer_queue.timer_next; 295 for (e = timer_queue.timer_next;
258 e != &timer_queue && timer > e->timer_delta; 296 e != &timer_queue && timer > e->timer_delta;
259 e = e->timer_next) 297 e = e->timer_next)
298 {
260 timer -= e->timer_delta; 299 timer -= e->timer_delta;
300 }
261 301
262 ev->timer_delta = timer; 302 ev->timer_delta = timer;
263 303
264 ev->timer_next = e; 304 ev->timer_next = e;
265 ev->timer_prev = e->timer_prev; 305 ev->timer_prev = e->timer_prev;