comparison src/event/modules/ngx_epoll_module.c @ 483:621229427cba release-0.1.16

nginx-0.1.16-RELEASE import *) 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; the bug had appeared in 0.1.14.
author Igor Sysoev <igor@sysoev.ru>
date Tue, 25 Jan 2005 12:27:35 +0000
parents fd661d14a7fa
children 64d9afb209da
comparison
equal deleted inserted replaced
482:49f5aef41157 483:621229427cba
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