diff -bur squid-3.0-PRE3-20031008-CVS/src/comm_epoll.cc squid-3.0-PRE3-20031008-EPOLL-FIXED/src/comm_epoll.cc --- squid-3.0-PRE3-20031008-CVS/src/comm_epoll.cc Sun Aug 3 18:38:15 2003 +++ squid-3.0-PRE3-20031008-EPOLL-FIXED/src/comm_epoll.cc Fri Oct 17 13:01:05 2003 @@ -94,6 +94,15 @@ } } +static const char* epolltype_atoi(int x) { + switch(x) { + case EPOLL_CTL_ADD: return "EPOLL_CTL_ADD"; + case EPOLL_CTL_DEL: return "EPOLL_CTL_DEL"; + case EPOLL_CTL_MOD: return "EPOLL_CTL_MOD"; + default: return "UNKNOWN_EPOLLCTL_OP"; + } +} + /* * comm_setselect * @@ -106,81 +115,37 @@ void *client_data, time_t timeout) { fde *F = &fd_table[fd]; - int change = 0; - int events = 0; - int pollin = 0; - int pollout = 0; - + int epoll_ctl_type = 0; struct epoll_event ev; assert(fd >= 0); assert(F->flags.open); debug(5, DEBUG_EPOLL ? 0 : 8) ("commSetSelect(fd=%d,type=%u,handler=%p,client_data=%p,timeout=%ld)\n", fd,type,handler,client_data,timeout); - if(F->read_handler != NULL) - pollin = 1; - - if(F->write_handler != NULL) - pollout = 1; + ev.events = 0; + ev.data.fd = fd; if (type & COMM_SELECT_READ) { - if(F->read_handler != handler) - change = 1; - - if(handler == NULL) - pollin = 0; - else - pollin = 1; - + if (handler) ev.events |= EPOLLIN | EPOLLHUP | EPOLLERR; F->read_handler = handler; - F->read_data = client_data; } if (type & COMM_SELECT_WRITE) { - if(F->write_handler != handler) - change = 1; - - if(handler == NULL) - pollout = 0; - else - pollout = 1; - + if (handler) ev.events |= EPOLLOUT | EPOLLHUP | EPOLLERR; F->write_handler = handler; - F->write_data = client_data; } - if(pollin) - events |= EPOLLIN; - - if(pollout) - events |= EPOLLOUT; - - if(events) - events |= EPOLLHUP | EPOLLERR; - - ev.data.fd = fd; - - ev.events = events; - - if(events) { - if (epoll_ctl(kdpfd, EPOLL_CTL_MOD, fd, &ev) < 0) { - if(errno == ENOENT) { - debug(5,4) ("commSetSelect: epoll_ctl(,EPOLL_CTL_MOD,,) failed on fd=%d: entry does not exist\n",fd); - - if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, fd, &ev) < 0) - debug(5,1) ("commSetSelect: cpoll_ctl(,EPOLL_CTL_ADD,,) failed on fd=%d!: %s\n",fd,xstrerror()); - } else { - debug(5,1) ("commSetSelect: cpoll_ctl(,EPOLL_CTL_MOD,,) failed on fd=%d!: %s\n",fd,xstrerror()); - } - } - } else if(change) { - if(epoll_ctl(kdpfd,EPOLL_CTL_DEL,fd,&ev) < 0) { - if(errno != ENOENT) - debug(5,1) ("commSetSelect: cpoll_ctl(,EPOLL_CTL_DEL,,) failed on fd=%d!: %s\n",fd,xstrerror()); - else - debug(5,4) ("commSetSelect: epoll_ctl(,EPOLL_CTL_DEL,,) failed on fd=%d: entry does not exist\n",fd); + if (ev.events != F->epoll_state) { + if (F->epoll_state) // already monitoring something. + epoll_ctl_type = ev.events ? EPOLL_CTL_MOD : EPOLL_CTL_DEL; + else epoll_ctl_type = EPOLL_CTL_ADD; + F->epoll_state = ev.events; + + if (epoll_ctl(kdpfd, epoll_ctl_type, fd, &ev) < 0) { + debug(5, DEBUG_EPOLL ? 0 : 8) ("commSetSelect: epoll_ctl(,%s,,): failed on fd=%d: %s\n", + epolltype_atoi(epoll_ctl_type), fd, xstrerror()); } } @@ -209,7 +174,6 @@ int num, i,fd; fde *F; PF *hdl; - struct epoll_event *cevents; static time_t last_timeout = 0; @@ -238,31 +202,48 @@ getCurrentTime(); + statHistCount(&statCounter.select_fds_hist, num); + if (num == 0) - return COMM_OK; /* No error.. */ + return COMM_TIMEOUT; /* No error.. */ + PROF_start(comm_handle_ready_fd); for (i = 0, cevents = pevents; i < num; i++, cevents++) { fd = cevents->data.fd; F = &fd_table[fd]; - debug(5, DEBUG_EPOLL ? 0 : 8) ("comm_select(): got fd=%d events=%d F->read_handler=%p F->write_handler=%p\n", - fd,cevents->events,F->read_handler,F->write_handler); + debug(5, DEBUG_EPOLL ? 0 : 8) ("comm_select(): got fd=%d events=%x monitoring=%x F->read_handler=%p F->write_handler=%p\n", + fd,cevents->events,F->epoll_state,F->read_handler,F->write_handler); - if(cevents->events & (EPOLLIN|EPOLLHUP|EPOLLERR)) { + //TODO: add EPOLLPRI?? + if (cevents->events & (EPOLLIN|EPOLLHUP|EPOLLERR)) { if((hdl = F->read_handler) != NULL) { debug(5, DEBUG_EPOLL ? 0 : 8) ("comm_select(): Calling read handler on fd=%d\n",fd); + PROF_start(comm_write_handler); F->read_handler = NULL; hdl(fd, F->read_data); + PROF_stop(comm_write_handler); + statCounter.select_fds++; + } else { + fd_table[fd].flags.read_pending = 1; + commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0); } } - if(cevents->events & (EPOLLOUT|EPOLLHUP|EPOLLERR)) { + if (cevents->events & (EPOLLOUT|EPOLLHUP|EPOLLERR)) { if((hdl = F->write_handler) != NULL) { debug(5, DEBUG_EPOLL ? 0 : 8) ("comm_select(): Calling write handler on fd=%d\n",fd); + PROF_start(comm_read_handler); F->write_handler = NULL; hdl(fd, F->write_data); + PROF_stop(comm_read_handler); + statCounter.select_fds++; + } else { + // remove interest since no handler exist for this event. + commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0); } } } + PROF_stop(comm_handle_ready_fd); return COMM_OK; } diff -bur squid-3.0-PRE3-20031008-CVS/src/fd.cc squid-3.0-PRE3-20031008-EPOLL-FIXED/src/fd.cc --- squid-3.0-PRE3-20031008-CVS/src/fd.cc Fri Feb 21 19:50:08 2003 +++ squid-3.0-PRE3-20031008-EPOLL-FIXED/src/fd.cc Thu Oct 16 13:08:44 2003 @@ -163,6 +163,7 @@ debug(51, 3) ("fd_open FD %d %s\n", fd, desc); F->type = type; F->flags.open = 1; + F->epoll_state = 0; #ifdef _SQUID_MSWIN_ switch (type) { diff -bur squid-3.0-PRE3-20031008-CVS/src/fde.h squid-3.0-PRE3-20031008-EPOLL-FIXED/src/fde.h --- squid-3.0-PRE3-20031008-CVS/src/fde.h Tue Jul 15 03:50:42 2003 +++ squid-3.0-PRE3-20031008-EPOLL-FIXED/src/fde.h Fri Oct 17 12:36:20 2003 @@ -99,6 +99,7 @@ int bytes_read; int bytes_written; int uses; /* ie # req's over persistent conn */ + unsigned epoll_state; struct _fde_disk disk; PF *read_handler;