Mercurial > hg > nginx-vendor-current
comparison src/event/modules/ngx_epoll_module.c @ 32:da8c190bdaba NGINX_0_1_16
nginx 0.1.16
*) Bugfix: if the response were transferred by chunks, then on the HEAD
request the final chunk was issued.
*) Bugfix: the "Connection: keep-alive" header were issued, even if the
keepalive_timeout directive forbade the keep-alive use.
*) Bugfix: the errors in the ngx_http_fastcgi_module caused the
segmentation faults.
*) Bugfix: the compressed response encrypted by SSL may not transferred
complete.
*) Bugfix: the TCP-specific TCP_NODELAY, TCP_NOPSUH, and TCP_CORK
options, are not used for the unix domain sockets.
*) Feature: the rewrite directive supports the arguments rewriting.
*) Bugfix: the response code 400 was returned for the POST request with
the "Content-Length: 0" header; bug appeared in 0.1.14.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 25 Jan 2005 00:00:00 +0300 |
parents | e1ada20fc595 |
children | 6cfc63e68377 |
comparison
equal
deleted
inserted
replaced
31:1b17dd824438 | 32:da8c190bdaba |
---|---|
196 } | 196 } |
197 | 197 |
198 | 198 |
199 static int ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags) | 199 static int ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags) |
200 { | 200 { |
201 int op, prev; | 201 int op; |
202 uint32_t events, prev; | |
202 ngx_event_t *e; | 203 ngx_event_t *e; |
203 ngx_connection_t *c; | 204 ngx_connection_t *c; |
204 struct epoll_event ee; | 205 struct epoll_event ee; |
205 | 206 |
206 c = ev->data; | 207 c = ev->data; |
208 | |
209 events = (uint32_t) event; | |
207 | 210 |
208 if (event == NGX_READ_EVENT) { | 211 if (event == NGX_READ_EVENT) { |
209 e = c->write; | 212 e = c->write; |
210 prev = EPOLLOUT; | 213 prev = EPOLLOUT; |
211 #if (NGX_READ_EVENT != EPOLLIN) | 214 #if (NGX_READ_EVENT != EPOLLIN) |
212 event = EPOLLIN; | 215 events = EPOLLIN; |
213 #endif | 216 #endif |
214 | 217 |
215 } else { | 218 } else { |
216 e = c->read; | 219 e = c->read; |
217 prev = EPOLLIN; | 220 prev = EPOLLIN; |
218 #if (NGX_WRITE_EVENT != EPOLLOUT) | 221 #if (NGX_WRITE_EVENT != EPOLLOUT) |
219 event = EPOLLOUT; | 222 events = EPOLLOUT; |
220 #endif | 223 #endif |
221 } | 224 } |
222 | 225 |
223 if (e->active) { | 226 if (e->active) { |
224 op = EPOLL_CTL_MOD; | 227 op = EPOLL_CTL_MOD; |
225 event |= prev; | 228 events |= prev; |
226 | 229 |
227 } else { | 230 } else { |
228 op = EPOLL_CTL_ADD; | 231 op = EPOLL_CTL_ADD; |
229 } | 232 } |
230 | 233 |
231 ee.events = event | flags; | 234 ee.events = events | flags; |
232 ee.data.u64 = (uintptr_t) c | ev->instance; | 235 ee.data.u64 = (uintptr_t) c | ev->instance; |
233 | 236 |
234 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, | 237 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, |
235 "epoll add event: fd:%d op:%d ev:%08XD", | 238 "epoll add event: fd:%d op:%d ev:%08XD", |
236 c->fd, op, ee.events); | 239 c->fd, op, ee.events); |
250 } | 253 } |
251 | 254 |
252 | 255 |
253 static int ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags) | 256 static int ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags) |
254 { | 257 { |
255 int op, prev; | 258 int op; |
259 uint32_t prev; | |
256 ngx_event_t *e; | 260 ngx_event_t *e; |
257 ngx_connection_t *c; | 261 ngx_connection_t *c; |
262 struct epoll_event ee; | |
263 | |
264 /* | |
265 * when the file descriptor is closed, the epoll automatically deletes | |
266 * it from its queue, so we do not need to delete explicity the event | |
267 * before the closing the file descriptor | |
268 */ | |
269 | |
270 if (flags & NGX_CLOSE_EVENT) { | |
271 ev->active = 0; | |
272 return NGX_OK; | |
273 } | |
274 | |
275 c = ev->data; | |
276 | |
277 if (event == NGX_READ_EVENT) { | |
278 e = c->write; | |
279 prev = EPOLLOUT; | |
280 | |
281 } else { | |
282 e = c->read; | |
283 prev = EPOLLIN; | |
284 } | |
285 | |
286 if (e->active) { | |
287 op = EPOLL_CTL_MOD; | |
288 ee.events = prev | flags; | |
289 ee.data.u64 = (uintptr_t) c | ev->instance; | |
290 | |
291 } else { | |
292 op = EPOLL_CTL_DEL; | |
293 ee.events = 0; | |
294 ee.data.ptr = NULL; | |
295 } | |
296 | |
297 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, | |
298 "epoll del event: fd:%d op:%d ev:%08XD", | |
299 c->fd, op, ee.events); | |
300 | |
301 if (epoll_ctl(ep, op, c->fd, &ee) == -1) { | |
302 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | |
303 "epoll_ctl(%d, %d) failed", op, c->fd); | |
304 return NGX_ERROR; | |
305 } | |
306 | |
307 ev->active = 0; | |
308 | |
309 return NGX_OK; | |
310 } | |
311 | |
312 | |
313 static int ngx_epoll_add_connection(ngx_connection_t *c) | |
314 { | |
315 struct epoll_event ee; | |
316 | |
317 ee.events = EPOLLIN|EPOLLOUT|EPOLLET; | |
318 ee.data.u64 = (uintptr_t) c | c->read->instance; | |
319 | |
320 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
321 "epoll add connection: fd:%d ev:%08XD", c->fd, ee.events); | |
322 | |
323 if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee) == -1) { | |
324 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
325 "epoll_ctl(EPOLL_CTL_ADD, %d) failed", c->fd); | |
326 return NGX_ERROR; | |
327 } | |
328 | |
329 c->read->active = 1; | |
330 c->write->active = 1; | |
331 | |
332 return NGX_OK; | |
333 } | |
334 | |
335 | |
336 static int ngx_epoll_del_connection(ngx_connection_t *c, u_int flags) | |
337 { | |
338 int op; | |
258 struct epoll_event ee; | 339 struct epoll_event ee; |
259 | 340 |
260 /* | 341 /* |
261 * when the file descriptor is closed the epoll automatically deletes | 342 * when the file descriptor is closed the epoll automatically deletes |
262 * it from its queue so we do not need to delete explicity the event | 343 * it from its queue so we do not need to delete explicity the event |
263 * before the closing the file descriptor | 344 * before the closing the file descriptor |
264 */ | 345 */ |
265 | 346 |
266 if (flags & NGX_CLOSE_EVENT) { | 347 if (flags & NGX_CLOSE_EVENT) { |
267 ev->active = 0; | |
268 return NGX_OK; | |
269 } | |
270 | |
271 c = ev->data; | |
272 | |
273 if (event == NGX_READ_EVENT) { | |
274 e = c->write; | |
275 prev = EPOLLOUT; | |
276 | |
277 } else { | |
278 e = c->read; | |
279 prev = EPOLLIN; | |
280 } | |
281 | |
282 if (e->active) { | |
283 op = EPOLL_CTL_MOD; | |
284 ee.events = prev | flags; | |
285 ee.data.u64 = (uintptr_t) c | ev->instance; | |
286 | |
287 } else { | |
288 op = EPOLL_CTL_DEL; | |
289 ee.events = 0; | |
290 ee.data.ptr = NULL; | |
291 } | |
292 | |
293 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, | |
294 "epoll del event: fd:%d op:%d ev:%08XD", | |
295 c->fd, op, ee.events); | |
296 | |
297 if (epoll_ctl(ep, op, c->fd, &ee) == -1) { | |
298 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | |
299 "epoll_ctl(%d, %d) failed", op, c->fd); | |
300 return NGX_ERROR; | |
301 } | |
302 | |
303 ev->active = 0; | |
304 | |
305 return NGX_OK; | |
306 } | |
307 | |
308 | |
309 static int ngx_epoll_add_connection(ngx_connection_t *c) | |
310 { | |
311 struct epoll_event ee; | |
312 | |
313 ee.events = EPOLLIN|EPOLLOUT|EPOLLET; | |
314 ee.data.u64 = (uintptr_t) c | c->read->instance; | |
315 | |
316 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
317 "epoll add connection: fd:%d ev:%08XD", c->fd, ee.events); | |
318 | |
319 if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee) == -1) { | |
320 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
321 "epoll_ctl(EPOLL_CTL_ADD, %d) failed", c->fd); | |
322 return NGX_ERROR; | |
323 } | |
324 | |
325 c->read->active = 1; | |
326 c->write->active = 1; | |
327 | |
328 return NGX_OK; | |
329 } | |
330 | |
331 | |
332 static int ngx_epoll_del_connection(ngx_connection_t *c, u_int flags) | |
333 { | |
334 int op; | |
335 struct epoll_event ee; | |
336 | |
337 /* | |
338 * when the file descriptor is closed the epoll automatically deletes | |
339 * it from its queue so we do not need to delete explicity the event | |
340 * before the closing the file descriptor | |
341 */ | |
342 | |
343 if (flags & NGX_CLOSE_EVENT) { | |
344 c->read->active = 0; | 348 c->read->active = 0; |
345 c->write->active = 0; | 349 c->write->active = 0; |
346 return NGX_OK; | 350 return NGX_OK; |
347 } | 351 } |
348 | 352 |
368 | 372 |
369 int ngx_epoll_process_events(ngx_cycle_t *cycle) | 373 int ngx_epoll_process_events(ngx_cycle_t *cycle) |
370 { | 374 { |
371 int events; | 375 int events; |
372 size_t n; | 376 size_t n; |
377 uint32_t revents; | |
373 ngx_int_t instance, i; | 378 ngx_int_t instance, i; |
374 ngx_uint_t lock, accept_lock, expire; | 379 ngx_uint_t lock, accept_lock, expire; |
375 ngx_err_t err; | 380 ngx_err_t err; |
376 ngx_log_t *log; | 381 ngx_log_t *log; |
377 ngx_msec_t timer; | 382 ngx_msec_t timer; |
519 | 524 |
520 #if (NGX_DEBUG0) | 525 #if (NGX_DEBUG0) |
521 log = c->log ? c->log : cycle->log; | 526 log = c->log ? c->log : cycle->log; |
522 #endif | 527 #endif |
523 | 528 |
529 revents = event_list[i].events; | |
530 | |
524 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, | 531 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, |
525 "epoll: fd:%d ev:%04XD d:%p", | 532 "epoll: fd:%d ev:%04XD d:%p", |
526 c->fd, event_list[i].events, event_list[i].data); | 533 c->fd, revents, event_list[i].data); |
527 | 534 |
528 if (event_list[i].events & (EPOLLERR|EPOLLHUP)) { | 535 if (revents & (EPOLLERR|EPOLLHUP)) { |
529 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, | 536 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, |
530 "epoll_wait() error on fd:%d ev:%04XD", | 537 "epoll_wait() error on fd:%d ev:%04XD", |
531 c->fd, event_list[i].events); | 538 c->fd, revents); |
532 } | 539 } |
533 | 540 |
534 if (event_list[i].events & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) { | 541 if (revents & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) { |
535 ngx_log_error(NGX_LOG_ALERT, log, 0, | 542 ngx_log_error(NGX_LOG_ALERT, log, 0, |
536 "strange epoll_wait() events fd:%d ev:%04XD", | 543 "strange epoll_wait() events fd:%d ev:%04XD", |
537 c->fd, event_list[i].events); | 544 c->fd, revents); |
545 } | |
546 | |
547 if ((revents & (EPOLLERR|EPOLLHUP)) | |
548 && (revents & (EPOLLIN|EPOLLOUT)) == 0) | |
549 { | |
550 /* | |
551 * if the error events were returned without EPOLLIN or EPOLLOUT, | |
552 * then add these flags to handle the events at least in one | |
553 * active handler | |
554 */ | |
555 | |
556 revents |= EPOLLIN|EPOLLOUT; | |
538 } | 557 } |
539 | 558 |
540 wev = c->write; | 559 wev = c->write; |
541 | 560 |
542 if ((event_list[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP)) | 561 if ((revents & EPOLLOUT) && wev->active) { |
543 && wev->active) | 562 |
544 { | |
545 if (ngx_threaded) { | 563 if (ngx_threaded) { |
546 wev->posted_ready = 1; | 564 wev->posted_ready = 1; |
547 ngx_post_event(wev); | 565 ngx_post_event(wev); |
548 | 566 |
549 } else { | 567 } else { |
562 * EPOLLIN must be handled after EPOLLOUT because we use | 580 * EPOLLIN must be handled after EPOLLOUT because we use |
563 * the optimization to avoid the unnecessary mutex locking/unlocking | 581 * the optimization to avoid the unnecessary mutex locking/unlocking |
564 * if the accept event is the last one. | 582 * if the accept event is the last one. |
565 */ | 583 */ |
566 | 584 |
567 if ((event_list[i].events & (EPOLLIN|EPOLLERR|EPOLLHUP)) | 585 if ((revents & EPOLLIN) && rev->active) { |
568 && rev->active) | 586 |
569 { | |
570 if (ngx_threaded && !rev->accept) { | 587 if (ngx_threaded && !rev->accept) { |
571 rev->posted_ready = 1; | 588 rev->posted_ready = 1; |
572 | 589 |
573 ngx_post_event(rev); | 590 ngx_post_event(rev); |
574 | 591 |