DOC_END
-NAME: defer_timeout
-COMMENT: (in minutes)
-TYPE: time_t
-LOC: Config.Timeout.defer
-DEFAULT: 1 hour
-DOC_START
- If your clients are behind slow (e.g. PPP/SLIP) connections,
- then data may come in from the server-side faster than it can
- be written to the client-side. When the server side gets too
- far ahead of the client-side, subsequent reads will be deferred
- until the client catches up. This timeout determines how long
- to wait while in "deferred read mode." The default is one
- hour.
-
-defer_timeout 1 hour
-DOC_END
-
-
NAME: request_timeout
TYPE: time_t
LOC: Config.Timeout.request
+
/*
- * $Id: client.cc,v 1.32 1997/10/20 22:59:43 wessels Exp $
+ * $Id: client.cc,v 1.33 1997/10/23 05:13:37 wessels Exp $
*
* DEBUG: section 0 WWW Client
* AUTHOR: Harvest Derived
+
/*
- * $Id: comm.cc,v 1.189 1997/10/23 04:01:23 wessels Exp $
+ * $Id: comm.cc,v 1.190 1997/10/23 05:13:37 wessels Exp $
*
* DEBUG: section 5 Socket Functions
* AUTHOR: Harvest Derived
static int fdIsHttpOrIcp _PARAMS((int fd));
static IPH commConnectDnsHandle;
static void commConnectCallback _PARAMS((ConnectStateData * cs, int status));
+static int commDeferRead(int fd);
static struct timeval zero_tv;
}
void
-comm_set_stall(int fd, int delta)
+commSetDefer(int fd, DEFER * func)
{
- if (fd < 0)
- return;
- fd_table[fd].stall_until = squid_curtime + delta;
+ fde *F = &fd_table[fd];
+ F->defer_check = func;
}
+static int
+commDeferRead(int fd)
+{
+ fde *F = &fd_table[fd];
+ if (F->defer_check == NULL)
+ return 0;
+ return F->defer_check(fd, F->read_data);
+}
#if HAVE_POLL
for (j = 0; j < NHttpSockets; j++) {
if (HttpSockets[j] < 0)
continue;
- if (fd_table[HttpSockets[j]].stall_until > squid_curtime)
+ if (commDeferRead(HttpSockets[j]))
continue;
fds[N++] = HttpSockets[j];
}
for (i = 0; i < NHttpSockets; i++) {
if (HttpSockets[i] < 0)
continue;
- if (fd_table[HttpSockets[i]].stall_until > squid_curtime)
+ if (commDeferRead(HttpSockets[i]))
continue;
fds[N++] = HttpSockets[i];
}
int events;
events = 0;
/* Check each open socket for a handler. */
- if (fd_table[i].read_handler && fd_table[i].stall_until <= squid_curtime)
+ if (fd_table[i].read_handler && !commDeferRead(i))
events |= POLLRDNORM;
if (fd_table[i].write_handler)
events |= POLLWRNORM;
maxfd = Biggest_FD + 1;
for (i = 0; i < maxfd; i++) {
/* Check each open socket for a handler. */
- if (fd_table[i].stall_until > squid_curtime)
- continue;
- if (fd_table[i].read_handler) {
+ if (fd_table[i].read_handler && !commDeferRead(i)) {
nfds++;
FD_SET(i, &readfds);
}
*/
#define ENTRY_VALIDATED (1<<16)
-#define READ_DEFERRED (1<<15)
+#define ENTRY_UNUSED15 (1<<15)
#define ENTRY_NEGCACHED (1<<14)
#define HIERARCHICAL (1<<13) /* can we query neighbors? */
#define KEY_PRIVATE (1<<12) /* is the key currently private? */
/*
- * $Id: ftp.cc,v 1.144 1997/10/22 18:51:15 wessels Exp $
+ * $Id: ftp.cc,v 1.145 1997/10/23 05:13:39 wessels Exp $
*
* DEBUG: section 9 File Transfer Protocol (FTP)
* AUTHOR: Harvest Derived
/* check if we want to defer reading */
clen = entry->mem_obj->inmem_hi;
off = storeLowestMemReaderOffset(entry);
- if ((clen - off) > READ_AHEAD_GAP) {
- IOStats.Ftp.reads_deferred++;
- debug(9, 3) ("ftpReadData: Read deferred for Object: %s\n",
- entry->url);
- commSetSelect(fd, COMM_SELECT_READ, ftpReadData, data, 0);
- if (!BIT_TEST(entry->flag, READ_DEFERRED)) {
- commSetTimeout(fd, Config.Timeout.defer, NULL, NULL);
- BIT_SET(entry->flag, READ_DEFERRED);
- }
- /* dont try reading again for a while */
- comm_set_stall(fd, 1);
- return;
- } else {
- BIT_RESET(entry->flag, READ_DEFERRED);
- }
if (EBIT_TEST(ftpState->flags, FTP_ISDIR))
if (!EBIT_TEST(ftpState->flags, FTP_HTML_HEADER_SENT))
ftpListingStart(ftpState);
ftpReadData,
ftpState,
0);
+ commSetDefer(ftpState->data.fd, protoCheckDeferRead);
ftpState->state = READING_DATA;
return;
} else if (!EBIT_TEST(ftpState->flags, FTP_TRIED_NLST)) {
ftpReadData,
ftpState,
0);
+ commSetDefer(ftpState->data.fd, protoCheckDeferRead);
ftpState->state = READING_DATA;
} else {
ftpFail(ftpState);
/*
- * $Id: gopher.cc,v 1.100 1997/10/22 05:50:29 wessels Exp $
+ * $Id: gopher.cc,v 1.101 1997/10/23 05:13:39 wessels Exp $
*
* DEBUG: section 10 Gopher
* AUTHOR: Harvest Derived
/* check if we want to defer reading */
clen = entry->mem_obj->inmem_hi;
off = storeLowestMemReaderOffset(entry);
- if ((clen - off) > READ_AHEAD_GAP) {
- IOStats.Gopher.reads_deferred++;
- debug(10, 3) ("gopherReadReply: Read deferred for Object: %s\n",
- entry->url);
- debug(10, 3) (" Current Gap: %d bytes\n", clen - off);
- /* reschedule, so it will automatically reactivated when
- * Gap is big enough. */
- commSetSelect(fd,
- COMM_SELECT_READ,
- gopherReadReply,
- data, 0);
- /* don't install read timeout until we are below the GAP */
- if (!BIT_TEST(entry->flag, READ_DEFERRED)) {
- commSetTimeout(fd, Config.Timeout.defer, NULL, NULL);
- BIT_SET(entry->flag, READ_DEFERRED);
- }
- /* dont try reading again for a while */
- comm_set_stall(fd, 1);
- return;
- } else {
- BIT_RESET(entry->flag, READ_DEFERRED);
- }
buf = get_free_4k_page();
errno = 0;
/* leave one space for \0 in gopherToHTML */
}
/* Schedule read reply. */
commSetSelect(fd, COMM_SELECT_READ, gopherReadReply, gopherState, 0);
+ commSetDefer(fd, protoCheckDeferRead);
if (buf)
put_free_4k_page(buf); /* Allocated by gopherSendRequest. */
}
+
/*
- * $Id: http.cc,v 1.193 1997/10/22 05:50:30 wessels Exp $
+ * $Id: http.cc,v 1.194 1997/10/23 05:13:40 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
/* check if we want to defer reading */
clen = entry->mem_obj->inmem_hi;
off = storeLowestMemReaderOffset(entry);
- if ((clen - off) > READ_AHEAD_GAP) {
- IOStats.Http.reads_deferred++;
- debug(11, 3) ("httpReadReply: Read deferred for Object: %s\n",
- entry->url);
- debug(11, 3) (" Current Gap: %d bytes\n", clen - off);
- /* reschedule, so it will be automatically reactivated
- * when Gap is big enough. */
- commSetSelect(fd,
- COMM_SELECT_READ,
- httpReadReply,
- httpState, 0);
- /* disable read timeout until we are below the GAP */
- if (!BIT_TEST(entry->flag, READ_DEFERRED)) {
- commSetTimeout(fd, Config.Timeout.defer, NULL, NULL);
- BIT_SET(entry->flag, READ_DEFERRED);
- }
- /* dont try reading again for a while */
- comm_set_stall(fd, 1);
- return;
- } else {
- BIT_RESET(entry->flag, READ_DEFERRED);
- }
errno = 0;
len = read(fd, buf, SQUID_TCP_SO_RCVBUF);
fd_bytes(fd, len, FD_READ);
COMM_SELECT_READ,
httpReadReply,
httpState, 0);
+ commSetDefer(fd, protoCheckDeferRead);
}
}
/*
- * $Id: main.cc,v 1.175 1997/10/20 22:59:47 wessels Exp $
+ * $Id: main.cc,v 1.176 1997/10/23 05:13:42 wessels Exp $
*
* DEBUG: section 1 Startup and Main Loop
* AUTHOR: Harvest Derived
continue;
comm_listen(fd);
commSetSelect(fd, COMM_SELECT_READ, httpAccept, NULL, 0);
+ commSetDefer(fd, httpAcceptDefer);
debug(1, 1) ("Accepting HTTP connections on port %d, FD %d.\n",
(int) u->i, fd);
HttpSockets[NHttpSockets++] = fd;
extern void comm_remove_close_handler _PARAMS((int fd, PF *, void *));
extern int comm_udp_send _PARAMS((int fd, const char *host, u_short port, const char *buf, int len));
extern int comm_udp_sendto _PARAMS((int fd, const struct sockaddr_in *, int size, const char *buf, int len));
-extern void comm_set_stall _PARAMS((int, int));
extern void comm_write _PARAMS((int fd,
char *buf,
int size,
FREE *));
extern void commCallCloseHandlers _PARAMS((int fd));
extern int commSetTimeout _PARAMS((int fd, int, PF *, void *));
+extern void commSetDefer(int fd, DEFER * func);
extern void _db_init _PARAMS((const char *logfile, const char *options));
extern void _db_rotate_log _PARAMS((void));
protocol_t));
extern PF icpHandleUdp;
extern PF httpAccept;
+extern DEFER httpAcceptDefer;
#ifdef SQUID_SNMP
extern PF snmpAccept;
#endif /* SQUID_SNMP */
extern int protoUnregister _PARAMS((StoreEntry *, request_t *, struct in_addr));
extern void protoStart _PARAMS((int, StoreEntry *, peer *, request_t *));
extern int protoAbortFetch _PARAMS((StoreEntry * entry));
-
+extern DEFER protoCheckDeferRead;
extern void redirectStart _PARAMS((clientHttpRequest *, RH *, void *));
extern void redirectOpenServers _PARAMS((void));
/*
- * $Id: stat.cc,v 1.160 1997/10/20 22:49:42 wessels Exp $
+ * $Id: stat.cc,v 1.161 1997/10/23 05:13:44 wessels Exp $
*
* DEBUG: section 18 Cache Manager Statistics
* AUTHOR: Harvest Derived
strcat(buf, "HI,");
if (BIT_TEST(flags, ENTRY_NEGCACHED))
strcat(buf, "NG,");
- if (BIT_TEST(flags, READ_DEFERRED))
- strcat(buf, "RD,");
if ((t = strrchr(buf, ',')))
*t = '\0';
return buf;
/*
- * $Id: stmem.cc,v 1.50 1997/10/22 17:07:25 wessels Exp $
+ * $Id: stmem.cc,v 1.51 1997/10/23 05:13:45 wessels Exp $
*
* DEBUG: section 19 Memory Primitives
* AUTHOR: Harvest Derived
p = p->next;
if (lastp) {
put_free_4k_page(lastp->data);
- store_mem_size -= SM_PAGE_SIZE;
+ store_mem_size -= SM_PAGE_SIZE;
safe_free(lastp);
}
}
time_t neighborTimeout;
struct {
time_t read;
- time_t defer;
time_t lifetime;
time_t connect;
time_t request;
void *timeout_data;
void *lifetime_data;
close_handler *close_handler; /* linked list */
- time_t stall_until; /* don't select for read until this time */
+ DEFER *defer_check; /* check if we should defer read */
CommWriteStateData *rwstate; /* State data for comm_write */
};
CommWriteStateData *commWriteState;
int nrequests;
int persistent;
+ struct {
+ int n;
+ time_t until;
+ } defer;
};
struct _ipcache_addrs {
typedef void IRCB _PARAMS((peer *, peer_t, icp_common_t *, void *data));
typedef void PSC _PARAMS((peer *, void *));
typedef void RH _PARAMS((void *data, char *result));
+typedef int DEFER(int fd, void *data);
typedef void SIH _PARAMS((int fd, void *)); /* swap in */
typedef int QS _PARAMS((const void *, const void *)); /* qsort */
/*
- * $Id: wais.cc,v 1.86 1997/10/21 19:38:54 wessels Exp $
+ * $Id: wais.cc,v 1.87 1997/10/23 05:13:46 wessels Exp $
*
* DEBUG: section 24 WAIS Relay
* AUTHOR: Harvest Derived
/* check if we want to defer reading */
clen = entry->mem_obj->inmem_hi;
off = storeLowestMemReaderOffset(entry);
- if ((clen - off) > READ_AHEAD_GAP) {
- IOStats.Wais.reads_deferred++;
- debug(24, 3) ("waisReadReply: Read deferred for Object: %s\n",
- entry->url);
- debug(24, 3) (" Current Gap: %d bytes\n", clen - off);
- /* reschedule, so it will automatically reactivated
- * when Gap is big enough. */
- commSetSelect(fd,
- COMM_SELECT_READ,
- waisReadReply,
- waisState, 0);
- /* don't install read handler while we're above the gap */
- if (!BIT_TEST(entry->flag, READ_DEFERRED)) {
- commSetTimeout(fd, Config.Timeout.defer, NULL, NULL);
- BIT_SET(entry->flag, READ_DEFERRED);
- }
- /* dont try reading again for a while */
- comm_set_stall(fd, 1);
- return;
- } else {
- BIT_RESET(entry->flag, READ_DEFERRED);
- }
len = read(fd, buf, 4096);
fd_bytes(fd, len, FD_READ);
debug(24, 5) ("waisReadReply: FD %d read len:%d\n", fd, len);
COMM_SELECT_READ,
waisReadReply,
waisState, 0);
+ commSetDefer(fd, protoCheckDeferRead);
}
}