--------------------- PatchSet 6584 Date: 2005/04/14 00:00:48 Author: swsf Branch: epoll-2_5 Tag: (none) Log: Changed the flow-control mechanism Made the comm_epoll function look more link comm_select and comm_poll Whitespace cleanup Members: src/client_side.c:1.47.2.59.2.2->1.47.2.59.2.3 src/comm.c:1.18.6.5.4.2->1.18.6.5.4.3 src/comm_select.c:1.8.6.6.22.2->1.8.6.6.22.3 src/forward.c:1.13.6.13.4.4->1.13.6.13.4.5 src/protos.h:1.41.6.22.4.4->1.41.6.22.4.5 src/store_swapout.c:1.11.2.1.32.3->1.11.2.1.32.4 src/structs.h:1.48.2.34.2.3->1.48.2.34.2.4 Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.47.2.59.2.2 retrieving revision 1.47.2.59.2.3 diff -u -r1.47.2.59.2.2 -r1.47.2.59.2.3 --- squid/src/client_side.c 29 Mar 2005 02:27:12 -0000 1.47.2.59.2.2 +++ squid/src/client_side.c 14 Apr 2005 00:00:48 -0000 1.47.2.59.2.3 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.47.2.59.2.2 2005/03/29 02:27:12 swsf Exp $ + * $Id: client_side.c,v 1.47.2.59.2.3 2005/04/14 00:00:48 swsf Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -2923,10 +2923,35 @@ { fde *F = &fd_table[fd]; ConnStateData *conn = data; - if (conn->body.size_left && !F->flags.socket_eof) - return conn->in.offset >= conn->in.size - 1; + if (conn->body.size_left && !F->flags.socket_eof) { + if(conn->in.offset >= conn->in.size - 1) { +#if HAVE_EPOLL + /* The commResumeFD function is called in this file */ + conn->in.clientfd=fd; + commDeferFD(fd); +#endif + return 1; + } + else + { + return 0; + } + } else - return conn->defer.until > squid_curtime; + { + if (conn->defer.until > squid_curtime ) { +#if HAVE_EPOLL + /* This is a second resolution timer, so commEpollBackon will + handle the resume for this defer call */ + commDeferFD(fd); +#endif + return 1; + } + else + { + return 0; + } + } } static void @@ -3328,6 +3353,15 @@ conn->body.size_left -= size; /* Move any remaining data */ conn->in.offset -= size; +#if HAVE_EPOLL + /* Resume the fd if necessary */ + if ( conn->in.clientfd ) { + if(conn->in.offset < conn->in.size - 1) { + commResumeFD(conn->in.clientfd); + conn->in.clientfd=0; + } + } +#endif if (conn->in.offset > 0) xmemmove(conn->in.buf, conn->in.buf + size, conn->in.offset); /* Remove request link if this is the last part of the body, as Index: squid/src/comm.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/comm.c,v retrieving revision 1.18.6.5.4.2 retrieving revision 1.18.6.5.4.3 diff -u -r1.18.6.5.4.2 -r1.18.6.5.4.3 --- squid/src/comm.c 18 Mar 2005 00:20:57 -0000 1.18.6.5.4.2 +++ squid/src/comm.c 14 Apr 2005 00:01:04 -0000 1.18.6.5.4.3 @@ -1,6 +1,6 @@ /* - * $Id: comm.c,v 1.18.6.5.4.2 2005/03/18 00:20:57 swsf Exp $ + * $Id: comm.c,v 1.18.6.5.4.3 2005/04/14 00:01:04 swsf Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -374,6 +374,11 @@ if (F->flags.nodelay) commSetTcpNoDelay(cs->fd); #endif + +#if HAVE_EPOLL + // If we are using epoll(), we need to make sure that this fd will be polled + commSetSelect(cs->fd,0,NULL,NULL,0); +#endif if (Config.tcpRcvBufsz > 0) commSetTcpRcvbuf(cs->fd, Config.tcpRcvBufsz); return 1; Index: squid/src/comm_select.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/comm_select.c,v retrieving revision 1.8.6.6.22.2 retrieving revision 1.8.6.6.22.3 diff -u -r1.8.6.6.22.2 -r1.8.6.6.22.3 --- squid/src/comm_select.c 18 Mar 2005 00:20:58 -0000 1.8.6.6.22.2 +++ squid/src/comm_select.c 14 Apr 2005 00:01:06 -0000 1.8.6.6.22.3 @@ -1,6 +1,6 @@ /* - * $Id: comm_select.c,v 1.8.6.6.22.2 2005/03/18 00:20:58 swsf Exp $ + * $Id: comm_select.c,v 1.8.6.6.22.3 2005/04/14 00:01:06 swsf Exp $ * * DEBUG: section 5 Socket Functions * @@ -1089,16 +1089,16 @@ switch(x) { case EPOLL_CTL_ADD: - return "EPOLL_CTL_ADD"; + return "EPOLL_CTL_ADD"; case EPOLL_CTL_DEL: - return "EPOLL_CTL_DEL"; + return "EPOLL_CTL_DEL"; case EPOLL_CTL_MOD: - return "EPOLL_CTL_MOD"; + return "EPOLL_CTL_MOD"; default: - return "UNKNOWN_EPOLLCTL_OP"; + return "UNKNOWN_EPOLLCTL_OP"; } } @@ -1112,12 +1112,17 @@ int j=0; for(i=0;iepoll_backoff)) { + continue; + } + /* If the fd is still meant to be backed off, add it to the start of the list and continue */ if(commDeferRead(fd) != 0) { @@ -1125,32 +1130,11 @@ continue; } - /* If the fd has been modified, do nothing */ - if(!(F->epoll_state)) { - continue; - } - - /* we need to re-add the fd to the epoll list */ - ev.events = F->epoll_state; - ev.data.fd = fd; - - /* Try and add the fd back into the epoll struct */ - if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, fd, &ev) < 0) { - /* If an unusual error occurs, log */ - if(errno != EEXIST) { - debug(5, 1) ("commEpollBackon: epoll_ctl(,%s,,): failed on fd=%d: %s\n",epolltype_atoi(EPOLL_CTL_ADD), fd, xstrerror()); - } - } - else - { - F->epoll_backoff=0; - } - } - else - { - /* Break on the first zero fd */ - break; - } + debug(5, 4) ("commEpollBackon: fd=%d\n",fd); + + /* Resume operations for this fd */ + commResumeFD(fd); + } } } @@ -1158,14 +1142,26 @@ /* Back off on the next epoll for the given fd */ void commEpollBackoff(int fd) { + commDeferFD(fd); +} + +/* Defer reads from this fd */ +void +commDeferFD(int fd) { fde *F = &fd_table[fd]; struct epoll_event ev; + int epoll_ctl_type = 0; int i; + /* Return if the fd is already backed off */ + if(F->epoll_backoff) { + return; + } + for(i=0;i= 0); assert(F->flags.open); - - /* we need to delete the fd from the epoll list */ + /* set up ev struct */ ev.events = 0; ev.data.fd = fd; - if (epoll_ctl(kdpfd, EPOLL_CTL_DEL, fd, &ev) < 0) { - /* If an unusual error occurs, log it */ - if(errno != ENOENT) { - debug(5, 1) ("commEpollBackoff: epoll_ctl(,%s,,): failed on fd=%d: %s\n",epolltype_atoi(EPOLL_CTL_DEL), fd, xstrerror()); - } + /* If we were only waiting for reads, delete the fd, otherwise remove the + read event */ + if(F->epoll_state == (EPOLLIN | EPOLLHUP | EPOLLERR)) { + epoll_ctl_type = EPOLL_CTL_DEL; + } + else + { + epoll_ctl_type = EPOLL_CTL_MOD; + ev.events = (F->epoll_state - EPOLLIN); + } + debug(5, 5) ("commDeferFD: epoll_ctl_type=%s, fd=%d epoll_state=%d\n",epolltype_atoi(epoll_ctl_type),fd,F->epoll_state); + + if (epoll_ctl(kdpfd, epoll_ctl_type, fd, &ev) < 0) { + /* If an error occurs, log it */ + debug(5, 1) ("commDeferFD: epoll_ctl(,%s,,): failed on fd=%d: %s\n",epolltype_atoi(epoll_ctl_type), fd, xstrerror()); } else { - backoff_fds[i]=fd; + backoff_fds[i]=fd; F->epoll_backoff=1; + F->epoll_state=ev.events; } } +/* Resume reading from the given fd */ +void +commResumeFD(int fd) { + struct epoll_event ev; + int epoll_ctl_type = 0; + fde *F; + + F=&fd_table[fd]; + /* If the fd has been modified, do nothing and remove the flag */ + if(!(F->read_handler) || !(F->epoll_backoff)) { + debug(5, 2) ("commResumeFD: fd=%d ignoring read_handler=%p, epoll_backoff=%d\n",fd,F->read_handler,F->epoll_backoff); + F->epoll_backoff=0; + return; + } + + /* we need to re-add the fd to the epoll list with EPOLLIN set */ + ev.events = F->epoll_state | EPOLLIN | EPOLLHUP | EPOLLERR; + ev.data.fd = fd; + + /* If epoll_state is not set, then this fd is only waiting for + reads, and needs adding, otherwise we mod it to add EPOLLIN*/ + if(!(F->epoll_state)) { + epoll_ctl_type = EPOLL_CTL_ADD; + } + else + { + epoll_ctl_type = EPOLL_CTL_MOD; + } + debug(5, 5) ("commResumeFD: epoll_ctl_type=%s, fd=%d\n",epolltype_atoi(epoll_ctl_type),fd); + + /* Try and add the fd back into the epoll struct */ + if (epoll_ctl(kdpfd, epoll_ctl_type, fd, &ev) < 0) { + /* If an error occurs, log */ + debug(5, 1) ("commResumeFD: epoll_ctl(,%s,,): failed on fd=%d: %s\n",epolltype_atoi(epoll_ctl_type), fd, xstrerror()); + } + else + { + F->epoll_backoff=0; + F->epoll_state=ev.events; + } +} void comm_select_init() { int i; pevents = (struct epoll_event *) xmalloc(SQUID_MAXFD * sizeof(struct epoll_event)); if (!pevents) { - fatalf("comm_select_init: xmalloc() failed: %s\n",xstrerror()); + fatalf("comm_select_init: xmalloc() failed: %s\n",xstrerror()); } kdpfd = epoll_create(SQUID_MAXFD); if (kdpfd < 0) { - fatalf("comm_select_init: epoll_create(): %s\n",xstrerror()); + fatalf("comm_select_init: epoll_create(): %s\n",xstrerror()); } for (i = 0; i < FD_SETSIZE; i++) { - backoff_fds[i]=0; + backoff_fds[i]=0; } } @@ -1241,61 +1288,67 @@ ev.data.fd = fd; if (type & COMM_SELECT_READ) { - if (handler) - ev.events |= EPOLLIN; + /* Only add the epoll event if the fd is not backed off */ + if (handler && !(F->epoll_backoff)) { + ev.events |= EPOLLIN; + } - F->read_handler = handler; - F->read_data = client_data; + F->read_handler = handler; + F->read_data = client_data; - // Otherwise, use previously stored value - } else if ((F->epoll_state & EPOLLIN) && (F->read_handler)) { - ev.events |= EPOLLIN; + // Otherwise, use previously stored value if the fd is not backed off + } else if ((F->epoll_state & EPOLLIN) && (F->read_handler) && !(F->epoll_backoff)) { + ev.events |= EPOLLIN; } if (type & COMM_SELECT_WRITE) { - if (handler) - ev.events |= EPOLLOUT; + if (handler) { + ev.events |= EPOLLOUT; + } - F->write_handler = handler; - F->write_data = client_data; + F->write_handler = handler; + F->write_data = client_data; - // Otherwise, use previously stored value + // Otherwise, use previously stored value } else if ((F->epoll_state & EPOLLOUT) && (F->write_handler)){ - ev.events |= EPOLLOUT; + ev.events |= EPOLLOUT; + } + + if (ev.events) { + ev.events |= EPOLLHUP | EPOLLERR; + } + + /* If the type is 0, force adding the fd to the epoll set */ + if(!(type)) { + F->epoll_state=0; } - if (ev.events) - ev.events |= EPOLLHUP | EPOLLERR; if (ev.events != F->epoll_state) { // If the struct is already in epoll MOD or DEL, else ADD - if (F->epoll_state) - epoll_ctl_type = ev.events ? EPOLL_CTL_MOD : EPOLL_CTL_DEL; - else - epoll_ctl_type = EPOLL_CTL_ADD; + if (F->epoll_state) { + epoll_ctl_type = ev.events ? EPOLL_CTL_MOD : EPOLL_CTL_DEL; + } + else + { + epoll_ctl_type = EPOLL_CTL_ADD; + } /* Update the state */ - F->epoll_state = ev.events; + F->epoll_state = ev.events; - /* If the FD is backed off, we just return. The update of - F->epoll_state will make sure that commEpollBackon sets the - correct epoll options when the fd is brought back online */ - if(F->epoll_backoff) - return; - - if (epoll_ctl(kdpfd, epoll_ctl_type, fd, &ev) < 0) { - debug(5, 1) ("commSetSelect: epoll_ctl(%s): failed on fd=%d: %s\n", - epolltype_atoi(epoll_ctl_type), fd, xstrerror()); - } + if (epoll_ctl(kdpfd, epoll_ctl_type, fd, &ev) < 0) { + debug(5, 1) ("commSetSelect: epoll_ctl(%s): failed on fd=%d: %s\n", + epolltype_atoi(epoll_ctl_type), fd, xstrerror()); + } } if (timeout) - F->timeout = squid_curtime + timeout; + F->timeout = squid_curtime + timeout; } int comm_epoll(int msec) { struct timespec ts; - int timeout; static time_t last_timeout = 0; int i; int num; @@ -1303,101 +1356,115 @@ fde *F; PF *hdl; struct epoll_event *cevents; + double timeout = current_dtime + (msec / 1000.0); if (msec > MAX_POLL_TIME) - msec = MAX_POLL_TIME; + msec = MAX_POLL_TIME; debug(50, 3)("comm_epoll: timeout %d\n", msec); - ts.tv_sec = msec/1000; - ts.tv_nsec = (msec % 1000) * 1000; - - timeout = msec/ 1000; - getCurrentTime(); - /* Check timeouts once per second */ - if (last_timeout < squid_curtime) { - last_timeout = squid_curtime; - checkTimeouts(); - } + do { +#if !ALARM_UPDATES_TIME + double start; + getCurrentTime(); + start = current_dtime; +#endif + ts.tv_sec = msec/1000; + ts.tv_nsec = (msec % 1000) * 1000; - /* Check for disk io callbacks */ - storeDirCallback(); + /* Check timeouts once per second */ + if (last_timeout < squid_curtime) { + last_timeout = squid_curtime; + checkTimeouts(); - /* bring backed off connections back online */ - commEpollBackon(); + /* bring backed off connections back online */ + commEpollBackon(); + } - for (;;) { - num = epoll_wait(kdpfd, pevents, SQUID_MAXFD, msec); - statCounter.select_loops++; + /* Check for disk io callbacks */ + storeDirCallback(); - if (num >= 0) - break; + for (;;) { + statCounter.syscalls.polls++; + num = epoll_wait(kdpfd, pevents, SQUID_MAXFD, msec); + statCounter.select_loops++; - if (ignoreErrno(errno)) - break; + if (num >= 0) + break; - getCurrentTime(); + if (ignoreErrno(errno)) + break; - return COMM_ERROR; - } + debug(5, 0) ("comm_epoll: epoll failure: %s\n", xstrerror()); - getCurrentTime(); + return COMM_ERROR; + } - statHistCount(&statCounter.select_fds_hist, num); + statHistCount(&statCounter.select_fds_hist, num); - if (num == 0) - return COMM_TIMEOUT; /* No error.. */ + if (num <= 0) + continue; - for (i = 0, cevents = pevents; i < num; i++, cevents++) { - fd = cevents->data.fd; - F = &fd_table[fd]; - debug(5, 8) ("comm_poll(): 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)) { - if((hdl = F->read_handler) != NULL) { - - // If the descriptor is meant to be deferred, don't handle yet - if(commDeferRead(fd)!=0) { - commEpollBackoff(fd); - goto WRITE_EVENT; - } + for (i = 0, cevents = pevents; i < num; i++, cevents++) { + fd = cevents->data.fd; + F = &fd_table[fd]; + debug(5, 8) ("comm_epoll(): 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)) { + if((hdl = F->read_handler) != NULL) { + + // If the descriptor is meant to be deferred, don't handle + if(commDeferRead(fd)!=0) { + if(!(F->epoll_backoff)) { + debug(5, 1) ("comm_epoll(): WARNING defer handler for fd=%d (desc=%s) does not call commDeferFD() - backing off manually\n",fd,F->desc); + commEpollBackoff(fd); + } + goto WRITE_EVENT; + } - debug(5, 8) ("comm_poll(): Calling read handler on fd=%d\n",fd); - F->read_handler = NULL; - hdl(fd, F->read_data); - if((F->read_handler == NULL) && (F->flags.open)) { - commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0); - } - statCounter.select_fds++; - } else if(cevents->events & EPOLLIN) { - debug(5, 2) ("comm_poll(): no read handler for fd=%d",fd); - if(F->flags.open) { - commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0); - } - } - } + debug(5, 8) ("comm_epoll(): Calling read handler on fd=%d\n",fd); + F->read_handler = NULL; + hdl(fd, F->read_data); + statCounter.select_fds++; + if((F->read_handler == NULL) && (F->flags.open)) { + commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0); + } + } else if(cevents->events & EPOLLIN) { + debug(5, 2) ("comm_epoll(): no read handler for fd=%d",fd); + if(F->flags.open) { + commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0); + } + } + } WRITE_EVENT: - if (cevents->events & (EPOLLOUT|EPOLLHUP|EPOLLERR)) { - if((hdl = F->write_handler) != NULL) { - debug(5,8) ("comm_poll(): Calling write handler on fd=%d\n",fd); - F->write_handler = NULL; - hdl(fd, F->write_data); - statCounter.select_fds++; - if((F->write_handler == NULL) && (F->flags.open)) { - commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0); - } - } else if(cevents->events & EPOLLOUT) { - debug(5, 2) ("comm_poll(): no write handler for fd=%d\n",fd); - if(F->flags.open) { - commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0); - } - } - } + if (cevents->events & (EPOLLOUT|EPOLLHUP|EPOLLERR)) { + if((hdl = F->write_handler) != NULL) { + debug(5,8) ("comm_epoll(): Calling write handler on fd=%d\n",fd); + F->write_handler = NULL; + hdl(fd, F->write_data); + statCounter.select_fds++; + if((F->write_handler == NULL) && (F->flags.open)) { + commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0); + } + } else if(cevents->events & EPOLLOUT) { + debug(5, 2) ("comm_epoll(): no write handler for fd=%d\n",fd); + if(F->flags.open) { + commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0); + } + } + } + } +#if !ALARM_UPDATES_TIME + getCurrentTime(); + statCounter.select_time += (current_dtime - start); +#endif + return COMM_OK; } + while (timeout > current_dtime); - /* End while loop */ - return COMM_OK; + debug(5, 8) ("comm_epoll: time out: %ld.\n", (long int) squid_curtime); + return COMM_TIMEOUT; } #endif /* HAVE_EPOLL */ Index: squid/src/forward.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/forward.c,v retrieving revision 1.13.6.13.4.4 retrieving revision 1.13.6.13.4.5 diff -u -r1.13.6.13.4.4 -r1.13.6.13.4.5 --- squid/src/forward.c 29 Mar 2005 08:32:38 -0000 1.13.6.13.4.4 +++ squid/src/forward.c 14 Apr 2005 00:01:07 -0000 1.13.6.13.4.5 @@ -1,6 +1,6 @@ /* - * $Id: forward.c,v 1.13.6.13.4.4 2005/03/29 08:32:38 swsf Exp $ + * $Id: forward.c,v 1.13.6.13.4.5 2005/04/14 00:01:07 swsf Exp $ * * DEBUG: section 17 Request Forwarding * AUTHOR: Duane Wessels @@ -703,11 +703,19 @@ */ if (mem->inmem_hi - mem->inmem_lo > SM_PAGE_SIZE + Config.Store.maxInMemObjSize + READ_AHEAD_GAP) { EBIT_SET(e->flags, ENTRY_DEFER_READ); +#if HAVE_EPOLL + mem->serverfd=fd; + commDeferFD(fd); +#endif return 1; } } if (mem->inmem_hi - storeLowestMemReaderOffset(e) > READ_AHEAD_GAP) { EBIT_SET(e->flags, ENTRY_DEFER_READ); +#if HAVE_EPOLL + mem->serverfd=fd; + commDeferFD(fd); +#endif return 1; } return rc; Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.41.6.22.4.4 retrieving revision 1.41.6.22.4.5 diff -u -r1.41.6.22.4.4 -r1.41.6.22.4.5 --- squid/src/protos.h 29 Mar 2005 03:00:06 -0000 1.41.6.22.4.4 +++ squid/src/protos.h 14 Apr 2005 00:01:07 -0000 1.41.6.22.4.5 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.41.6.22.4.4 2005/03/29 03:00:06 swsf Exp $ + * $Id: protos.h,v 1.41.6.22.4.5 2005/04/14 00:01:07 swsf Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -159,6 +159,10 @@ extern int comm_openex(int, int, struct in_addr, u_short, int, unsigned char TOS, const char *); extern u_short comm_local_port(int fd); +#if HAVE_EPOLL +extern void commDeferFD(int fd); +extern void commResumeFD(int fd); +#endif extern void commSetSelect(int, unsigned int, PF *, void *, time_t); extern void comm_add_close_handler(int fd, PF *, void *); extern void comm_remove_close_handler(int fd, PF *, void *); Index: squid/src/store_swapout.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/store_swapout.c,v retrieving revision 1.11.2.1.32.3 retrieving revision 1.11.2.1.32.4 diff -u -r1.11.2.1.32.3 -r1.11.2.1.32.4 --- squid/src/store_swapout.c 29 Mar 2005 03:00:08 -0000 1.11.2.1.32.3 +++ squid/src/store_swapout.c 14 Apr 2005 00:01:09 -0000 1.11.2.1.32.4 @@ -1,6 +1,6 @@ /* - * $Id: store_swapout.c,v 1.11.2.1.32.3 2005/03/29 03:00:08 swsf Exp $ + * $Id: store_swapout.c,v 1.11.2.1.32.4 2005/04/14 00:01:09 swsf Exp $ * * DEBUG: section 20 Storage Manager Swapout Functions * AUTHOR: Duane Wessels @@ -154,8 +154,20 @@ if (mem->inmem_lo != new_mem_lo) { mem->inmem_lo = stmemFreeDataUpto(&mem->data_hdr, new_mem_lo); - /* The read may not be deferred any longer */ - EBIT_CLR(e->flags, ENTRY_DEFER_READ); + /* If ENTRY_DEFER_READ is set, then the client side will continue to + flush until it has less than READ_AHEAD_GAP bytes in memory */ + if (EBIT_TEST(e->flags, ENTRY_DEFER_READ)) { + + if (mem->inmem_hi - mem->inmem_lo <= READ_AHEAD_GAP) { + EBIT_CLR(e->flags, ENTRY_DEFER_READ); +#if HAVE_EPOLL + if(mem->serverfd !=0) { + commResumeFD(mem->serverfd); + mem->serverfd=0; + } +#endif + } + } } return on_disk; Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.48.2.34.2.3 retrieving revision 1.48.2.34.2.4 diff -u -r1.48.2.34.2.3 -r1.48.2.34.2.4 --- squid/src/structs.h 29 Mar 2005 03:00:08 -0000 1.48.2.34.2.3 +++ squid/src/structs.h 14 Apr 2005 00:01:16 -0000 1.48.2.34.2.4 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.48.2.34.2.3 2005/03/29 03:00:08 swsf Exp $ + * $Id: structs.h,v 1.48.2.34.2.4 2005/04/14 00:01:16 swsf Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -785,8 +785,8 @@ squid_off_t bytes_written; int uses; /* ie # req's over persistent conn */ #if HAVE_EPOLL - unsigned epoll_state; - unsigned epoll_backoff; + unsigned epoll_state; /* keep track of the epoll state */ + unsigned epoll_backoff; /* keep track of whether the fd is backed off */ #endif struct _fde_disk { DWCB *wrt_handle; @@ -1107,6 +1107,10 @@ char *buf; size_t offset; size_t size; +#if HAVE_EPOLL + int clientfd; /* Record the client's fd if we have too much + data waiting to send to the server */ +#endif } in; struct { squid_off_t size_left; /* How much body left to process */ @@ -1497,6 +1501,10 @@ mem_hdr data_hdr; squid_off_t inmem_hi; squid_off_t inmem_lo; +#if HAVE_EPOLL + int serverfd; /* Record the server's fd if we have too much + data waiting to send to the client */ +#endif dlink_list clients; int nclients; struct {