comparison src/event/modules/ngx_kqueue_module.c @ 69:e43f406e4525

nginx-0.0.1-2003-03-20-19:09:44 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 20 Mar 2003 16:09:44 +0000
parents 5a7d1aaa1618
children eacfdd1c31b9
comparison
equal deleted inserted replaced
68:d549fdc17d7e 69:e43f406e4525
108 int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) 108 int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
109 { 109 {
110 ev->active = 1; 110 ev->active = 1;
111 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; 111 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
112 112
113 /* The event addition or change should be always passed to a kernel
114 because there can be case when event was passed to a kernel then
115 added again to the change_list and then deleted from the change_list
116 by ngx_kqueue_del_event() so the first event still remains in a kernel */
117
118 #if 0
119
113 if (nchanges > 0 120 if (nchanges > 0
114 && ev->index < nchanges 121 && ev->index < nchanges
115 && change_list[ev->index].udata == ev) 122 && change_list[ev->index].udata == ev)
116 { 123 {
117 #if (NGX_DEBUG_EVENT) 124 #if (NGX_DEBUG_EVENT)
118 ngx_connection_t *c = (ngx_connection_t *) ev->data; 125 ngx_connection_t *c = (ngx_connection_t *) ev->data;
119 ngx_log_debug(ev->log, "kqueue add event: %d: ft:%d" _ c->fd _ event); 126 ngx_log_debug(ev->log, "kqueue add event: %d: ft:%d" _ c->fd _ event);
120 #endif 127 #endif
128
129 /* if the event is still not passed to a kernel we change it */
130
121 change_list[ev->index].filter = event; 131 change_list[ev->index].filter = event;
122 change_list[ev->index].flags = flags; 132 change_list[ev->index].flags = flags;
123 133
124 return NGX_OK; 134 return NGX_OK;
125 } 135 }
136
137 #endif
126 138
127 return ngx_kqueue_set_event(ev, event, EV_ADD | flags); 139 return ngx_kqueue_set_event(ev, event, EV_ADD | flags);
128 } 140 }
129 141
130 142
140 { 152 {
141 #if (NGX_DEBUG_EVENT) 153 #if (NGX_DEBUG_EVENT)
142 ngx_connection_t *c = (ngx_connection_t *) ev->data; 154 ngx_connection_t *c = (ngx_connection_t *) ev->data;
143 ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _ c->fd _ event); 155 ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _ c->fd _ event);
144 #endif 156 #endif
157
158 /* if the event is still not passed to a kernel we will not pass it */
159
145 if (ev->index < --nchanges) { 160 if (ev->index < --nchanges) {
146 e = (ngx_event_t *) change_list[nchanges].udata; 161 e = (ngx_event_t *) change_list[nchanges].udata;
147 change_list[ev->index] = change_list[nchanges]; 162 change_list[ev->index] = change_list[nchanges];
148 e->index = ev->index; 163 e->index = ev->index;
149 } 164 }
150 165
151 return NGX_OK; 166 return NGX_OK;
152 } 167 }
168
169 /* when a socket is closed kqueue automatically deletes its filters
170 so we do not need to delete a event explicity before a socket closing */
153 171
154 if (flags & NGX_CLOSE_EVENT) { 172 if (flags & NGX_CLOSE_EVENT) {
155 return NGX_OK; 173 return NGX_OK;
156 } 174 }
157 175
254 nchanges = 0; 272 nchanges = 0;
255 273
256 if (timer) { 274 if (timer) {
257 gettimeofday(&tv, NULL); 275 gettimeofday(&tv, NULL);
258 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; 276 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
277
278 /* Expired timers must be deleted before the events processing
279 because the new timers can be added during the processing */
280
281 ngx_event_expire_timers(delta);
259 282
260 } else { 283 } else {
261 if (events == 0) { 284 if (events == 0) {
262 ngx_log_error(NGX_LOG_ALERT, log, 0, 285 ngx_log_error(NGX_LOG_ALERT, log, 0,
263 "kevent returns no events without timeout"); 286 "kevent returns no events without timeout");
293 continue; 316 continue;
294 } 317 }
295 318
296 ev = (ngx_event_t *) event_list[i].udata; 319 ev = (ngx_event_t *) event_list[i].udata;
297 320
321 /* It's a stale event from a socket
322 that was just closed in this iteration */
323
298 if (!ev->active) { 324 if (!ev->active) {
299 continue; 325 continue;
300 } 326 }
301 327
302 switch (event_list[i].filter) { 328 switch (event_list[i].filter) {
303 329
304 case EVFILT_READ: 330 case EVFILT_READ:
305 case EVFILT_WRITE: 331 case EVFILT_WRITE:
332
333 if (ev->first) {
334 if (nchanges > 0
335 && ev->index < nchanges
336 && change_list[ev->index].udata == ev) {
337
338 /* It's a stale event from a socket that was just closed
339 in this iteration and during processing another socket
340 was opened with the same number by accept() or socket()
341 and its event has been added the event to the change_list
342 but has not been passed to a kernel. Nevertheless
343 there's small chance that ngx_kqueue_set_event() has
344 flushed the new event if the change_list was filled up.
345 In this very rare case we would get EAGAIN while
346 a reading or a writing */
347
348 continue;
349
350 } else {
351 ev->first = 0;
352 }
353 }
354
306 ev->available = event_list[i].data; 355 ev->available = event_list[i].data;
307 356
308 if (event_list[i].flags & EV_EOF) { 357 if (event_list[i].flags & EV_EOF) {
309 ev->eof = 1; 358 ev->eof = 1;
310 ev->error = event_list[i].fflags; 359 ev->error = event_list[i].fflags;
330 ngx_log_error(NGX_LOG_ALERT, log, 0, 379 ngx_log_error(NGX_LOG_ALERT, log, 0,
331 "unknown kevent filter %d" _ event_list[i].filter); 380 "unknown kevent filter %d" _ event_list[i].filter);
332 } 381 }
333 } 382 }
334 383
335 if (timer) {
336 ngx_event_expire_timers(delta);
337 }
338
339 return NGX_OK; 384 return NGX_OK;
340 } 385 }