Mercurial > hg > nginx-quic
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 } |