/*
- * $Id: client_side.cc,v 1.100 1997/05/02 04:28:34 wessels Exp $
+ * $Id: client_side.cc,v 1.101 1997/05/05 03:43:38 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
#include "squid.h"
static RH clientRedirectDone;
-static void icpHandleIMSReply _PARAMS((int fd, StoreEntry * entry, void *data));
+static PIF icpHandleIMSReply;
static int clientGetsOldEntry _PARAMS((StoreEntry * new, StoreEntry * old, request_t * request));
static int checkAccelOnly _PARAMS((icpStateData * icpState));
}
icpParseRequestHeaders(icpState);
fd_note(fd, icpState->url);
- if (!BIT_TEST(icpState->request->flags, REQ_PROXY_KEEPALIVE)) {
- commSetSelect(fd,
- COMM_SELECT_READ,
- icpDetectClientClose,
- icpState,
- 0);
- }
icpProcessRequest(fd, icpState);
}
/*
- * $Id: comm.cc,v 1.149 1997/05/02 21:34:04 wessels Exp $
+ * $Id: comm.cc,v 1.150 1997/05/05 03:43:38 wessels Exp $
*
* DEBUG: section 5 Socket Functions
* AUTHOR: Harvest Derived
if (shutdown_pending > 0 || reread_pending > 0)
setSocketShutdownLifetimes(Config.shutdownLifetime);
else
- setSocketShutdownLifetimes(0);
+ setSocketShutdownLifetimes(1);
}
nfds = 0;
maxfd = Biggest_FD + 1;
/* Select for Writing on FD, until SIZE bytes are sent. Call
* * HANDLER when complete. */
void
-comm_write(int fd, char *buf, int size, CWCB * handler, void *handler_data, FREE *free_func)
+comm_write(int fd, char *buf, int size, CWCB * handler, void *handler_data, FREE * free_func)
{
CommWriteStateData *state = NULL;
debug(5, 5, "comm_write: FD %d: sz %d: hndl %p: data %p.\n",
fd, size, handler, handler_data);
- if (fd_table[fd].rwstate) {
- debug(5, 1, "WARNING: FD %d: A comm_write is already active.\n", fd);
- CommWriteStateCallbackAndFree(fd, COMM_ERROR);
- }
+ if (fd_table[fd].rwstate)
+ fatal_dump("comm_write: comm_write is already active");
state = xcalloc(1, sizeof(CommWriteStateData));
state->buf = buf;
state->size = size;
/*
- * $Id: disk.cc,v 1.67 1997/05/02 21:34:06 wessels Exp $
+ * $Id: disk.cc,v 1.68 1997/05/05 03:43:39 wessels Exp $
*
* DEBUG: section 6 Disk I/O Routines
* AUTHOR: Harvest Derived
/* Open a disk file. Return a file descriptor */
int
-file_open(const char *path, int mode, FOCB *callback, void *callback_data)
+file_open(const char *path, int mode, FOCB * callback, void *callback_data)
{
int fd;
open_ctrl_t *ctrlp;
/* Open file */
#if USE_ASYNC_IO
if (callback != NULL) {
- aioOpen(path, mode, 0644, file_open_complete, ctrlp);
- return DISK_OK;
+ aioOpen(path, mode, 0644, file_open_complete, ctrlp);
+ return DISK_OK;
}
#endif
fd = open(path, mode, 0644);
int len,
FILE_WRITE_HD handle,
void *handle_data,
- void (*free_func) _PARAMS((void *)))
+ FREE * free_func)
{
dwrite_q *wq = NULL;
FD_ENTRY *fde;
/*
- * $Id: dns.cc,v 1.33 1997/04/30 18:30:47 wessels Exp $
+ * $Id: dns.cc,v 1.34 1997/05/05 03:43:40 wessels Exp $
*
* DEBUG: section 34 Dnsserver interface
* AUTHOR: Harvest Derived
};
static int dnsOpenServer _PARAMS((const char *command));
+static PF dnsShutdownRead;
static dnsserver_t **dns_child_table = NULL;
NULL, /* Handler */
NULL, /* Handler-data */
xfree);
+ commSetSelect(dnsData->inpipe,
+ COMM_SELECT_READ,
+ dnsShutdownRead,
+ dnsData,
+ 0);
dnsData->flags |= DNS_FLAG_CLOSING;
}
}
+
+static void
+dnsShutdownRead(int fd, void *data)
+{
+ dnsserver_t *dnsData = data;
+ debug(14, dnsData->flags & DNS_FLAG_CLOSING ? 5 : 1,
+ "FD %d: Connection from DNSSERVER #%d is closed, disabling\n",
+ fd,
+ dnsData->id);
+ dnsData->flags = 0;
+ commSetSelect(fd,
+ COMM_SELECT_WRITE,
+ NULL,
+ NULL, 0);
+ comm_close(fd);
+}
fd_close(int fd)
{
FD_ENTRY *fde = &fd_table[fd];
+ if (fde->type == FD_FILE) {
+ if (fde->read_handler)
+ fatal_dump("file_close: read_handler present");
+ if (fde->write_handler)
+ fatal_dump("file_close: write_handler present");
+ }
fdUpdateBiggest(fd, fde->open = FD_CLOSE);
memset(fde, '\0', sizeof(FD_ENTRY));
fde->timeout = 0;
void
fdFreeMemory(void)
{
- safe_free(fd_table);
+ safe_free(fd_table);
+}
+
+void
+fdDumpOpen(void)
+{
+ int i;
+ FD_ENTRY *fde;
+ for (i = 0; i < Squid_MaxFD; i++) {
+ fde = &fd_table[i];
+ if (!fde->open)
+ continue;
+ if (i == fileno(debug_log))
+ continue;
+ debug(5, 1, "Open FD %4d %s\n", i, fde->desc);
+ }
}
/*
- * $Id: fqdncache.cc,v 1.52 1997/05/02 04:28:34 wessels Exp $
+ * $Id: fqdncache.cc,v 1.53 1997/05/05 03:43:42 wessels Exp $
*
* DEBUG: section 35 FQDN Cache
* AUTHOR: Harvest Derived
{
dnsserver_t *dnsData = data;
int len;
- int svc_time;
int n;
fqdncache_entry *f = NULL;
fqdncache_entry *x = NULL;
fatal_dump("fqdncache_dnsHandleRead: bad status");
if (strstr(dnsData->ip_inbuf, "$end\n")) {
/* end of record found */
- svc_time = tvSubMsec(dnsData->dispatch_time, current_time);
- if (n > FQDNCACHE_AV_FACTOR)
- n = FQDNCACHE_AV_FACTOR;
- FqdncacheStats.avg_svc_time
- = (FqdncacheStats.avg_svc_time * (n - 1) + svc_time) / n;
+ FqdncacheStats.avg_svc_time =
+ intAverage(FqdncacheStats.avg_svc_time,
+ tvSubMsec(dnsData->dispatch_time, current_time),
+ n, FQDNCACHE_AV_FACTOR);
if ((x = fqdncache_parsebuffer(dnsData->ip_inbuf, dnsData)) == NULL) {
debug(35, 0, "fqdncache_dnsHandleRead: fqdncache_parsebuffer failed?!\n");
} else {
/*
- * $Id: ftp.cc,v 1.103 1997/04/30 18:30:50 wessels Exp $
+ * $Id: ftp.cc,v 1.104 1997/05/05 03:43:42 wessels Exp $
*
* DEBUG: section 9 File Transfer Protocol (FTP)
* AUTHOR: Harvest Derived
} ftp_ctrl_t;
/* Local functions */
-static const char *ftpTransferMode _PARAMS((const char *));
-static char *ftpGetBasicAuth _PARAMS((const char *));
-static void ftpStateFree _PARAMS((int, void *));
-static void ftpReadReply _PARAMS((int, void *));
-static void ftpStartComplete _PARAMS((void *, int));
-static void ftpConnectDone _PARAMS((int fd, int status, void *data));
+static CNCB ftpConnectDone;
+static CWCB ftpSendComplete;
+static PF ftpReadReply;
+static PF ftpSendRequest;
+static PF ftpServerClosed;
+static PF ftpStateFree;
static PF ftpTimeout;
+static char *ftpGetBasicAuth _PARAMS((const char *));
+static const char *ftpTransferMode _PARAMS((const char *));
static void ftpProcessReplyHeader _PARAMS((FtpStateData *, const char *, int));
-static void ftpSendComplete _PARAMS((int, char *, int, int, void *));
-static void ftpSendRequest _PARAMS((int, void *));
-static void ftpServerClosed _PARAMS((int, void *));
-static void ftp_login_parser _PARAMS((const char *, FtpStateData *));
+static void ftpStartComplete _PARAMS((void *, int));
+static void ftpLoginParser _PARAMS((const char *, FtpStateData *));
/* External functions */
extern char *base64_decode _PARAMS((const char *coded));
}
static void
-ftp_login_parser(const char *login, FtpStateData * ftpState)
+ftpLoginParser(const char *login, FtpStateData * ftpState)
{
char *s = NULL;
xstrncpy(ftpState->user, login, MAX_URL);
{
char *orig_user;
char *auth;
- ftp_login_parser(ftpState->request->login, ftpState);
+ ftpLoginParser(ftpState->request->login, ftpState);
if (ftpState->user[0] && ftpState->password[0])
return 1; /* name and passwd both in URL */
if (!ftpState->user[0] && !ftpState->password[0])
if ((auth = ftpGetBasicAuth(req_hdr)) == NULL)
return 0; /* need auth header */
orig_user = xstrdup(ftpState->user);
- ftp_login_parser(auth, ftpState);
+ ftpLoginParser(auth, ftpState);
if (!strcmp(orig_user, ftpState->user)) {
xfree(orig_user);
return 1; /* same username */
/*
- * $Id: gopher.cc,v 1.77 1997/04/30 18:30:52 wessels Exp $
+ * $Id: gopher.cc,v 1.78 1997/05/05 03:43:43 wessels Exp $
*
* DEBUG: section 10 Gopher
* AUTHOR: Harvest Derived
StoreEntry *entry = datap;
char *url = entry->url;
GopherStateData *gopherState = CreateGopherStateData();
- int sock;
+ int fd;
gopherState->entry = entry;
debug(10, 3, "gopherStart: url: %s\n", url);
/* Parse url. */
return;
}
/* Create socket. */
- sock = comm_open(SOCK_STREAM,
+ fd = comm_open(SOCK_STREAM,
0,
Config.Addrs.tcp_outgoing,
0,
COMM_NONBLOCKING,
url);
- if (sock == COMM_ERROR) {
+ if (fd == COMM_ERROR) {
debug(10, 4, "gopherStart: Failed because we're out of sockets.\n");
squid_error_entry(entry, ERR_NO_FDS, xstrerror());
gopherStateFree(-1, gopherState);
return;
}
- comm_add_close_handler(sock,
+ comm_add_close_handler(fd,
gopherStateFree,
gopherState);
/* check if IP is already in cache. It must be.
if (!ipcache_gethostbyname(gopherState->host, 0)) {
debug(10, 4, "gopherStart: Called without IP entry in ipcache. OR lookup failed.\n");
squid_error_entry(entry, ERR_DNS_FAIL, dns_error_message);
- comm_close(sock);
+ comm_close(fd);
return;
}
if (((gopherState->type_id == GOPHER_INDEX) || (gopherState->type_id == GOPHER_CSO))
}
gopherToHTML(gopherState, (char *) NULL, 0);
storeComplete(entry);
- comm_close(sock);
+ comm_close(fd);
return;
}
- commSetTimeout(sock, Config.Timeout.connect, gopherTimeout, gopherState);
- commConnectStart(sock,
+ commSetTimeout(fd, Config.Timeout.connect, gopherTimeout, gopherState);
+ commConnectStart(fd,
gopherState->host,
gopherState->port,
gopherConnectDone,
/*
- * $Id: http.cc,v 1.158 1997/04/30 20:06:28 wessels Exp $
+ * $Id: http.cc,v 1.159 1997/05/05 03:43:44 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
HDR_MISC_END
} http_hdr_misc_t;
-typedef struct proxy_ctrl_t {
- int sock;
- request_t *orig_request;
- StoreEntry *entry;
- peer *e;
-} proxy_ctrl_t;
-
-typedef struct http_ctrl_t {
- int sock;
- request_t *request;
- char *req_hdr;
- int req_hdr_sz;
- StoreEntry *entry;
-} http_ctrl_t;
-
static char *HttpServerCCStr[] =
{
"public",
int cc[SCC_ENUM_END];
} ReplyHeaderStats;
-static void httpStateFree _PARAMS((int fd, void *));
-static PF httpTimeout;
-static void httpMakePublic _PARAMS((StoreEntry *));
-static void httpMakePrivate _PARAMS((StoreEntry *));
-static void httpCacheNegatively _PARAMS((StoreEntry *));
-static void httpReadReply _PARAMS((int fd, void *));
-static void httpSendComplete _PARAMS((int fd, char *, int, int, void *));
-static void proxyhttpStartComplete _PARAMS((void *, int));
-static void httpStartComplete _PARAMS((void *, int));
-static void httpSendRequest _PARAMS((int fd, void *));
+static CNCB httpConnectDone;
+static CWCB httpSendComplete;
static IPH httpConnect;
-static void httpConnectDone _PARAMS((int fd, int status, void *data));
+static PF httpReadReply;
+static PF httpSendRequest;
+static PF httpStateFree;
+static PF httpTimeout;
static void httpAppendRequestHeader _PARAMS((char *hdr, const char *line, size_t * sz, size_t max));
-
+static void httpCacheNegatively _PARAMS((StoreEntry *));
+static void httpMakePrivate _PARAMS((StoreEntry *));
+static void httpMakePublic _PARAMS((StoreEntry *));
static void
httpStateFree(int fd, void *data)
StoreEntry * entry,
peer * e)
{
- proxy_ctrl_t *ctrlp;
- int sock;
+ HttpStateData *httpState;
+ request_t *request;
+ int fd;
debug(11, 3, "proxyhttpStart: \"%s %s\"\n",
RequestMethodStr[orig_request->method], entry->url);
debug(11, 10, "proxyhttpStart: HTTP request header:\n%s\n",
if (e->options & NEIGHBOR_PROXY_ONLY)
storeStartDeleteBehind(entry);
/* Create socket. */
- sock = comm_open(SOCK_STREAM,
+ fd = comm_open(SOCK_STREAM,
0,
Config.Addrs.tcp_outgoing,
0,
COMM_NONBLOCKING,
entry->url);
- if (sock == COMM_ERROR) {
+ if (fd == COMM_ERROR) {
debug(11, 4, "proxyhttpStart: Failed because we're out of sockets.\n");
squid_error_entry(entry, ERR_NO_FDS, xstrerror());
return COMM_ERROR;
}
- ctrlp = xmalloc(sizeof(proxy_ctrl_t));
- ctrlp->sock = sock;
- ctrlp->orig_request = orig_request;
- ctrlp->entry = entry;
- ctrlp->e = e;
- storeLockObject(entry, proxyhttpStartComplete, ctrlp);
- return COMM_OK;
-}
-
-
-static void
-proxyhttpStartComplete(void *data, int status)
-{
- proxy_ctrl_t *ctrlp = data;
- int sock = ctrlp->sock;
- request_t *orig_request = ctrlp->orig_request;
- StoreEntry *entry = ctrlp->entry;
- peer *e = ctrlp->e;
- char *url = entry->url;
- HttpStateData *httpState = NULL;
- request_t *request = NULL;
- int fd = ctrlp->sock;
- xfree(ctrlp);
+ storeLockObject(entry, NULL, NULL);
httpState = xcalloc(1, sizeof(HttpStateData));
httpState->entry = entry;
httpState->req_hdr = entry->mem_obj->mime_hdr;
httpState->request = requestLink(request);
httpState->neighbor = e;
httpState->orig_request = requestLink(orig_request);
- httpState->fd = sock;
+ httpState->fd = fd;
/* register the handler to free HTTP state data when the FD closes */
comm_add_close_handler(httpState->fd,
httpStateFree,
request->method = orig_request->method;
xstrncpy(request->host, e->host, SQUIDHOSTNAMELEN);
request->port = e->http_port;
- xstrncpy(request->urlpath, url, MAX_URL);
+ xstrncpy(request->urlpath, entry->url, MAX_URL);
BIT_SET(request->flags, REQ_PROXYING);
httpState->ip_lookup_pending = 1;
ipcache_nbgethostbyname(request->host,
httpState->fd,
httpConnect,
httpState);
- return;
+ return COMM_OK;
}
static void
int req_hdr_sz,
StoreEntry * entry)
{
- http_ctrl_t *ctrlp;
- int sock;
+ int fd;
+ HttpStateData *httpState;
debug(11, 3, "httpStart: \"%s %s\"\n",
RequestMethodStr[request->method], entry->url);
debug(11, 10, "httpStart: req_hdr '%s'\n", req_hdr);
/* Create socket. */
- sock = comm_open(SOCK_STREAM,
+ fd = comm_open(SOCK_STREAM,
0,
Config.Addrs.tcp_outgoing,
0,
COMM_NONBLOCKING,
entry->url);
- if (sock == COMM_ERROR) {
+ if (fd == COMM_ERROR) {
debug(11, 4, "httpStart: Failed because we're out of sockets.\n");
squid_error_entry(entry, ERR_NO_FDS, xstrerror());
return COMM_ERROR;
}
- ctrlp = xmalloc(sizeof(http_ctrl_t));
- ctrlp->sock = sock;
- ctrlp->request = request;
- ctrlp->req_hdr = req_hdr;
- ctrlp->req_hdr_sz = req_hdr_sz;
- ctrlp->entry = entry;
- storeLockObject(entry, httpStartComplete, ctrlp);
- return COMM_OK;
-}
-
-
-static void
-httpStartComplete(void *data, int status)
-{
- http_ctrl_t *ctrlp = (http_ctrl_t *) data;
- HttpStateData *httpState = NULL;
- int sock;
- request_t *request;
- char *req_hdr;
- int req_hdr_sz;
- StoreEntry *entry;
-
- sock = ctrlp->sock;
- request = ctrlp->request;
- req_hdr = ctrlp->req_hdr;
- req_hdr_sz = ctrlp->req_hdr_sz;
- entry = ctrlp->entry;
- xfree(ctrlp);
-
+ storeLockObject(entry, NULL, NULL);
httpState = xcalloc(1, sizeof(HttpStateData));
httpState->entry = entry;
-
httpState->req_hdr = req_hdr;
httpState->req_hdr_sz = req_hdr_sz;
httpState->request = requestLink(request);
- httpState->fd = sock;
+ httpState->fd = fd;
comm_add_close_handler(httpState->fd,
httpStateFree,
httpState);
- commSetTimeout(sock, Config.Timeout.read, httpTimeout, httpState);
+ commSetTimeout(fd, Config.Timeout.read, httpTimeout, httpState);
httpState->ip_lookup_pending = 1;
ipcache_nbgethostbyname(request->host,
httpState->fd,
httpConnect,
httpState);
+ return COMM_OK;
}
void
/*
- * $Id: ipcache.cc,v 1.113 1997/04/30 20:06:31 wessels Exp $
+ * $Id: ipcache.cc,v 1.114 1997/05/05 03:43:46 wessels Exp $
*
* DEBUG: section 14 IP Cache
* AUTHOR: Harvest Derived
static void ipcacheAddHostent _PARAMS((ipcache_entry *, const struct hostent *));
static int ipcacheHasPending _PARAMS((ipcache_entry *));
static ipcache_entry *ipcache_get _PARAMS((const char *));
-static void dummy_handler _PARAMS((int, const ipcache_addrs *, void *));
+static IPH dummy_handler;
static int ipcacheExpiredEntry _PARAMS((ipcache_entry *));
static void ipcacheAddPending _PARAMS((ipcache_entry *, int fd, IPH *, void *));
static void ipcacheEnqueue _PARAMS((ipcache_entry *));
static HashID ip_table = 0;
static struct ipcacheQueueData *ipcacheQueueHead = NULL;
static struct ipcacheQueueData **ipcacheQueueTailP = &ipcacheQueueHead;
+static int queue_length = 0;
static char ipcache_status_char[] =
{
new->i = i;
*ipcacheQueueTailP = new;
ipcacheQueueTailP = &new->next;
+ queue_length++;
}
static void *
if (ipcacheQueueHead == NULL)
ipcacheQueueTailP = &ipcacheQueueHead;
safe_free(old);
+ queue_length--;
}
if (i && i->status != IP_PENDING)
debug_trap("ipcacheDequeue: status != IP_PENDING");
{
dnsserver_t *dnsData = data;
int len;
- int svc_time;
int n;
ipcache_entry *i = NULL;
ipcache_entry *x = NULL;
fatal_dump("ipcache_dnsHandleRead: bad status");
if (strstr(dnsData->ip_inbuf, "$end\n")) {
/* end of record found */
- svc_time = tvSubMsec(dnsData->dispatch_time, current_time);
- if (n > IPCACHE_AV_FACTOR)
- n = IPCACHE_AV_FACTOR;
- IpcacheStats.avg_svc_time
- = (IpcacheStats.avg_svc_time * (n - 1) + svc_time) / n;
+ IpcacheStats.avg_svc_time = intAverage(IpcacheStats.avg_svc_time,
+ tvSubMsec(dnsData->dispatch_time, current_time),
+ n, IPCACHE_AV_FACTOR);
if ((x = ipcache_parsebuffer(dnsData->ip_inbuf, dnsData)) == NULL) {
debug(14, 0, "ipcache_dnsHandleRead: ipcache_parsebuffer failed?!\n");
} else {
dnsData->data = NULL;
dnsData->flags &= ~DNS_FLAG_BUSY;
}
- /* reschedule */
- commSetSelect(dnsData->inpipe,
- COMM_SELECT_READ,
- ipcache_dnsHandleRead,
- dnsData, 0);
ipcacheNudgeQueue();
}
IpcacheStats.release_locked);
storeAppendPrintf(sentry, "{dnsserver avg service time: %d msec}\n",
IpcacheStats.avg_svc_time);
+ storeAppendPrintf(sentry, "{pending queue length: %d}\n", queue_length);
storeAppendPrintf(sentry, "}\n\n");
storeAppendPrintf(sentry, "{IP Cache Contents:\n\n");
storeAppendPrintf(sentry, " {%-29.29s %5s %6s %6s %1s}\n",
/*
- * $Id: neighbors.cc,v 1.138 1997/05/01 04:25:41 wessels Exp $
+ * $Id: neighbors.cc,v 1.139 1997/05/05 03:43:47 wessels Exp $
*
* DEBUG: section 15 Neighbor Routines
* AUTHOR: Harvest Derived
n = ++p->stats.pings_acked;
if ((icp_opcode) header->opcode <= ICP_OP_END)
p->stats.counts[header->opcode]++;
- if (n > RTT_AV_FACTOR)
- n = RTT_AV_FACTOR;
if (mem) {
rtt = tvSubMsec(mem->start_ping, current_time);
- p->stats.rtt = (p->stats.rtt * (n - 1) + rtt) / n;
+ p->stats.rtt = intAverage(p->stats.rtt, rtt, n, RTT_AV_FACTOR);
p->icp_version = (int) header->version;
}
}
ps_state *psstate = data;
peer *p = psstate->callback_data;
StoreEntry *fake = psstate->entry;
- double old;
- double new;
- double D;
p->mcast.flags &= ~PEER_COUNTING;
- D = (double) ++p->mcast.n_times_counted;
- if (D > 10.0)
- D = 10.0;
- old = p->mcast.avg_n_members;
- new = (double) psstate->icp.n_recv;
- p->mcast.avg_n_members = (old * (D - 1.0) + new) / D;
+ p->mcast.avg_n_members = doubleAverage(p->mcast.avg_n_members,
+ (double) psstate->icp.n_recv,
+ ++p->mcast.n_times_counted,
+ 10);
debug(15, 1, "Group %s: %d replies, %4.1f average\n",
p->host,
psstate->icp.n_recv,
/*
- * $Id: redirect.cc,v 1.40 1997/04/30 22:46:26 wessels Exp $
+ * $Id: redirect.cc,v 1.41 1997/05/05 03:43:48 wessels Exp $
*
* DEBUG: section 29 Redirector
* AUTHOR: Duane Wessels
redirectStateData *r = redirector->redirectState;
char *t = NULL;
int n;
- int svc_time;
len = read(fd,
redirector->inbuf + redirector->offset,
redirector->flags &= ~REDIRECT_FLAG_BUSY;
redirector->offset = 0;
n = ++RedirectStats.replies;
- svc_time = tvSubMsec(redirector->dispatch_time, current_time);
- if (n > REDIRECT_AV_FACTOR)
- n = REDIRECT_AV_FACTOR;
- RedirectStats.avg_svc_time
- = (RedirectStats.avg_svc_time * (n - 1) + svc_time) / n;
+ RedirectStats.avg_svc_time =
+ intAverage(RedirectStats.avg_svc_time,
+ tvSubMsec(redirector->dispatch_time, current_time),
+ n, REDIRECT_AV_FACTOR);
}
}
while ((redirector = GetFirstAvailable()) && (r = Dequeue()))
/*
- * $Id: store.cc,v 1.228 1997/05/02 21:34:15 wessels Exp $
+ * $Id: store.cc,v 1.229 1997/05/05 03:43:49 wessels Exp $
*
* DEBUG: section 20 Storeage Manager
* AUTHOR: Harvest Derived
{
if (BIT_TEST(e->flag, RELEASE_REQUEST))
return;
- if (!storeEntryLocked(e)) {
- debug_trap("Someone called storeReleaseRequest on an unlocked entry");
- debug(20, 0, " --> '%s'\n", e->url ? e->url : "NULL URL");
- return;
- }
- debug(20, 3, "storeReleaseRequest: FOR '%s'\n", e->key ? e->key : e->url);
- e->flag |= RELEASE_REQUEST;
+ if (!storeEntryLocked(e))
+ fatal_dump("storeReleaseRequest: unlocked entry");
+ debug(20, 3, "storeReleaseRequest: '%s'\n", e->key);
+ BIT_SET(e->flag, RELEASE_REQUEST);
storeSetPrivateKey(e);
}
if (e->lock_count)
return (int) e->lock_count;
if (e->store_status == STORE_PENDING) {
- debug_trap("storeUnlockObject: Someone unlocked STORE_PENDING object");
- debug(20, 1, " --> Key '%s'\n", e->key);
- e->store_status = STORE_ABORTED;
+ if (BIT_TEST(e->flag, ENTRY_DISPATCHED)) {
+ debug_trap("storeUnlockObject: PENDING and DISPATCHED with 0 locks");
+ debug(20, 1, " --> Key '%s'\n", e->key);
+ e->store_status = STORE_ABORTED;
+ } else {
+ BIT_SET(e->flag, RELEASE_REQUEST);
+ }
}
if (storePendingNClients(e) > 0)
debug_trap("storeUnlockObject: unlocked entry with pending clients\n");
{
StoreEntry *e = NULL;
- debug(20, 5, "StoreAddDiskRestore: '%s': size %d: expires %d: file_number %d\n",
+ debug(20, 5, "StoreAddDiskRestore: '%s': size %d: expires %d: fileno=%08X\n",
url, size, expires, file_number);
/* if you call this you'd better be sure file_number is not
storeSetMemStatus(e, NOT_IN_MEMORY);
e->swap_status = SWAP_OK;
e->swap_file_number = file_number;
- storeDirMapBitSet(file_number);
e->object_len = size;
e->lock_count = 0;
BIT_RESET(e->flag, CLIENT_ABORT_REQUEST);
e->expires = expires;
e->lastmod = lastmod;
e->ping_status = PING_NONE;
- if (store_rebuilding == STORE_REBUILDING_CLEAN)
+ if (store_rebuilding == STORE_REBUILDING_CLEAN) {
BIT_SET(e->flag, ENTRY_VALIDATED);
- else
+ /* Only set the file bit if we know its a valid entry */
+ /* otherwise, set it in the validation procedure */
+ storeDirMapBitSet(file_number);
+ } else {
BIT_RESET(e->flag, ENTRY_VALIDATED);
+ }
return e;
}
e);
return;
}
+ if (mem->e_current_len > e->object_len)
+ debug_trap("storeSwapInHandle: Too much data read!");
/* complete swapping in */
storeSetMemStatus(e, IN_MEMORY);
put_free_8k_page(mem->e_swap_buf);
debug(20, 5, "storeSwapInHandle: SwapIn complete: '%s' from %s.\n",
e->url, storeSwapFullPath(e->swap_file_number, NULL));
if (mem->e_current_len != e->object_len) {
- debug(20, 0, "storeSwapInHandle: WARNING: Object size mismatch.\n");
+ debug_trap("storeSwapInHandle: Object size mismatch");
debug(20, 0, " --> '%s'\n", e->url);
debug(20, 0, " --> Expecting %d bytes from file: %s\n", e->object_len,
storeSwapFullPath(e->swap_file_number, NULL));
put_free_8k_page(mem->e_swap_buf);
file_close(fd);
if (e->swap_file_number != -1) {
- storeDirMapBitReset(e->swap_file_number);
storePutUnusedFileno(e->swap_file_number);
e->swap_file_number = -1;
}
if (x < 1)
continue;
storeSwapFullPath(sfileno, swapfile);
- if (x != 6) {
- storePutUnusedFileno(sfileno);
+ if (x != 6)
continue;
- }
if (sfileno < 0)
continue;
sfileno = storeDirProperFileno(d->dirn, sfileno);
lastmod = (time_t) scan3;
size = (off_t) scan4;
- if ((e = storeGet(url))) {
- if (e->timestamp > timestamp) {
- /* already have a newer object in memory, throw old one away */
- debug(20, 3, "storeRebuildFromDisk: Replaced: %s\n", url);
- RB->dupcount++;
- continue;
- }
- debug(20, 6, "storeRebuildFromDisk: Duplicate: '%s'\n", url);
- storeRelease(e);
- RB->objcount--;
- RB->dupcount++;
- }
e = storeGet(url);
used = storeDirMapBitTest(sfileno);
/* If this URL already exists in the cache, does the swap log
path = storeSwapFullPath(e->swap_file_number, NULL);
retcode = stat(path, sb);
}
- if (retcode < 0 || sb->st_size == 0 || sb->st_size != e->object_len)
+ if (retcode < 0 || sb->st_size == 0 || sb->st_size != e->object_len) {
BIT_RESET(e->flag, ENTRY_VALIDATED);
- else
+ } else {
BIT_SET(e->flag, ENTRY_VALIDATED);
+ storeDirMapBitSet(e->swap_file_number);
+ }
errno = errcode;
(ctrlp->callback) (ctrlp->callback_data, retcode);
xfree(sb);
debug(20, 5, "storeRelease: Release anonymous object\n");
if (e->swap_status == SWAP_OK && (e->swap_file_number > -1)) {
- storePutUnusedFileno(e->swap_file_number);
+ if (BIT_TEST(e->flag, ENTRY_VALIDATED))
+ storePutUnusedFileno(e->swap_file_number);
storeDirUpdateSwapSize(e->swap_file_number, e->object_len, -1);
- storeDirMapBitReset(e->swap_file_number);
e->swap_file_number = -1;
HTTPCacheInfo->proto_purgeobject(HTTPCacheInfo,
urlParseProtocol(e->url),
safeunlink(new[dirn], 1);
safeunlink(cln[dirn], 1);
fd[dirn] = file_open(new[dirn],
- O_WRONLY | O_CREAT | O_TRUNC,
- NULL,
- NULL);
+ O_WRONLY | O_CREAT | O_TRUNC,
+ NULL,
+ NULL);
if (fd[dirn] < 0) {
debug(50, 0, "storeWriteCleanLogs: %s: %s\n", new[dirn], xstrerror());
continue;
xfree(list);
hashFreeMemory(store_table);
safe_free(MaintBucketsOrder);
+ storeDirCloseSwapLogs();
}
int
static int
storeGetUnusedFileno(void)
{
+ int fn;
if (fileno_stack_count < 1)
return -1;
- return fileno_stack[--fileno_stack_count];
+ fn = fileno_stack[--fileno_stack_count];
+ storeDirMapBitSet(fn);
+ return fn;
}
static void
storePutUnusedFileno(int fileno)
{
+ if (!storeDirMapBitTest(fileno))
+ fatal_dump("storePutUnusedFileno: fileno not in use");
+ storeDirMapBitReset(fileno);
if (fileno_stack_count < FILENO_STACK_SIZE)
fileno_stack[fileno_stack_count++] = fileno;
else
int
storeDirMapAllocate(void)
{
+ int fn;
int dirn = storeMostFreeSwapDir();
SwapDir *SD = &SwapDirs[dirn];
int filn = file_map_allocate(SD->map, SD->suggest);
- return (dirn << SWAP_DIR_SHIFT) | (filn & SWAP_FILE_MASK);
+ fn = (dirn << SWAP_DIR_SHIFT) | (filn & SWAP_FILE_MASK);
+ return fn;
}
char *
if (SD->swaplog_fd >= 0)
file_close(SD->swaplog_fd);
/* open a write-only FD for the new log */
- fd = file_open(new_path, O_WRONLY | O_CREAT, NULL, NULL);
+ fd = file_open(new_path, O_WRONLY | O_CREAT | O_TRUNC, NULL, NULL);
if (fd < 0) {
debug(50, 1, "%s: %s\n", new_path, xstrerror());
fatal("storeDirOpenTmpSwapLog: Failed to open swap log.");
/*
- * $Id: tools.cc,v 1.103 1997/05/02 21:34:17 wessels Exp $
+ * $Id: tools.cc,v 1.104 1997/05/05 03:43:50 wessels Exp $
*
* DEBUG: section 21 Misc Functions
* AUTHOR: Harvest Derived
}
static void
-dumpMallocStats(FILE * f)
+dumpMallocStats()
{
#if HAVE_MALLINFO
struct mallinfo mp;
if (!do_mallinfo)
return;
mp = mallinfo();
- fprintf(f, "Memory usage for %s via mallinfo():\n", appname);
- fprintf(f, "\ttotal space in arena: %6d KB\n",
+ fprintf(debug_log, "Memory usage for %s via mallinfo():\n", appname);
+ fprintf(debug_log, "\ttotal space in arena: %6d KB\n",
mp.arena >> 10);
- fprintf(f, "\tOrdinary blocks: %6d KB %6d blks\n",
+ fprintf(debug_log, "\tOrdinary blocks: %6d KB %6d blks\n",
mp.uordblks >> 10, mp.ordblks);
- fprintf(f, "\tSmall blocks: %6d KB %6d blks\n",
+ fprintf(debug_log, "\tSmall blocks: %6d KB %6d blks\n",
mp.usmblks >> 10, mp.smblks);
- fprintf(f, "\tHolding blocks: %6d KB %6d blks\n",
+ fprintf(debug_log, "\tHolding blocks: %6d KB %6d blks\n",
mp.hblkhd >> 10, mp.hblks);
- fprintf(f, "\tFree Small blocks: %6d KB\n",
+ fprintf(debug_log, "\tFree Small blocks: %6d KB\n",
mp.fsmblks >> 10);
- fprintf(f, "\tFree Ordinary blocks: %6d KB\n",
+ fprintf(debug_log, "\tFree Ordinary blocks: %6d KB\n",
mp.fordblks >> 10);
t = mp.uordblks + mp.usmblks + mp.hblkhd;
- fprintf(f, "\tTotal in use: %6d KB %d%%\n",
+ fprintf(debug_log, "\tTotal in use: %6d KB %d%%\n",
t >> 10, percent(t, mp.arena));
t = mp.fsmblks + mp.fordblks;
- fprintf(f, "\tTotal free: %6d KB %d%%\n",
+ fprintf(debug_log, "\tTotal free: %6d KB %d%%\n",
t >> 10, percent(t, mp.arena));
#if HAVE_EXT_MALLINFO
- fprintf(f, "\tmax size of small blocks:\t%d\n",
+ fprintf(debug_log, "\tmax size of small blocks:\t%d\n",
mp.mxfast);
- fprintf(f, "\tnumber of small blocks in a holding block:\t%d\n",
+ fprintf(debug_log, "\tnumber of small blocks in a holding block:\t%d\n",
mp.nlblks);
- fprintf(f, "\tsmall block rounding factor:\t%d\n",
+ fprintf(debug_log, "\tsmall block rounding factor:\t%d\n",
mp.grain);
- fprintf(f, "\tspace (including overhead) allocated in ord. blks:\t%d\n",
+ fprintf(debug_log, "\tspace (including overhead) allocated in ord. blks:\t%d\n",
mp.uordbytes);
- fprintf(f, "\tnumber of ordinary blocks allocated:\t%d\n",
+ fprintf(debug_log, "\tnumber of ordinary blocks allocated:\t%d\n",
mp.allocated);
- fprintf(f, "\tbytes used in maintaining the free tree:\t%d\n",
+ fprintf(debug_log, "\tbytes used in maintaining the free tree:\t%d\n",
mp.treeoverhead);
#endif /* HAVE_EXT_MALLINFO */
#if PRINT_MMAP
#endif /* HAVE_MALLINFO */
}
-static int
-PrintRusage(void (*f) (void), FILE * lf)
+static void
+PrintRusage(void)
{
#if HAVE_GETRUSAGE && defined(RUSAGE_SELF)
struct rusage rusage;
#ifdef _SQUID_SOLARIS_
leave_suid();
#endif
- fprintf(lf, "CPU Usage: user %d sys %d\n",
+ fprintf(debug_log, "CPU Usage: user %d sys %d\n",
(int) rusage.ru_utime.tv_sec, (int) rusage.ru_stime.tv_sec);
#if defined(_SQUID_SGI_) || defined(_SQUID_OSF_) || defined(BSD4_4)
- fprintf(lf, "Maximum Resident Size: %ld KB\n", rusage.ru_maxrss);
+ fprintf(debug_log, "Maximum Resident Size: %ld KB\n", rusage.ru_maxrss);
#else /* _SQUID_SGI_ */
- fprintf(lf, "Maximum Resident Size: %ld KB\n",
+ fprintf(debug_log, "Maximum Resident Size: %ld KB\n",
(rusage.ru_maxrss * getpagesize()) >> 10);
#endif /* _SQUID_SGI_ */
- fprintf(lf, "Page faults with physical i/o: %ld\n",
+ fprintf(debug_log, "Page faults with physical i/o: %ld\n",
rusage.ru_majflt);
#endif /* HAVE_GETRUSAGE */
- dumpMallocStats(lf);
- if (f)
- f();
- return 0;
}
void
#endif
releaseServerSockets();
storeWriteCleanLogs();
- PrintRusage(NULL, debug_log);
+ PrintRusage();
+ dumpMallocStats();
if (squid_curtime - SQUID_RELEASE_TIME < 864000) {
/* skip if more than 10 days old */
if (Config.adminEmail)
releaseServerSockets();
unlinkdClose();
storeWriteCleanLogs();
- PrintRusage(NULL, debug_log);
+ PrintRusage();
+ dumpMallocStats();
storeCloseLog();
statCloseLog();
#if PURIFY
configFreeMemory();
storeFreeMemory();
- fdFreeMemory();
dnsFreeMemory();
redirectFreeMemory();
errorpageFreeMemory();
ipcacheFreeMemory();
fqdncacheFreeMemory();
#endif
+ file_close(0);
+ file_close(1);
+ file_close(2);
+ fdDumpOpen();
+ fdFreeMemory();
debug(21, 0, "Squid Cache (Version %s): Exiting normally.\n",
version_string);
fclose(debug_log);
fprintf(debug_log, "Squid Cache (Version %s): Terminated abnormally.\n",
version_string);
fflush(debug_log);
- PrintRusage(NULL, debug_log);
+ PrintRusage();
+ dumpMallocStats();
}
/* fatal */
void
writePidFile(void)
{
- FILE *pid_fp = NULL;
+ int fd;
const char *f = NULL;
mode_t old_umask;
-
- if ((f = Config.pidFilename) == NULL || !strcmp(Config.pidFilename, "none"))
+ char buf[32];
+ if ((f = Config.pidFilename) == NULL)
+ return;
+ if (!strcmp(Config.pidFilename, "none"))
return;
enter_suid();
old_umask = umask(022);
- pid_fp = fopen(f, "w");
+ fd = file_open(f, O_WRONLY | O_CREAT | O_TRUNC, NULL, NULL);
umask(old_umask);
leave_suid();
- if (pid_fp != NULL) {
- fprintf(pid_fp, "%d\n", (int) getpid());
- fclose(pid_fp);
- } else {
- debug(50, 0, "WARNING: Could not write pid file\n");
- debug(50, 0, " %s: %s\n", f, xstrerror());
+ if (fd < 0) {
+ debug(50, 0, "%s: %s\n", f, xstrerror());
+ debug_trap("Could not write pid file");
+ return;
}
+ sprintf(buf, "%d\n", (int) getpid());
+ write(fd, buf, strlen(buf));
+ file_close(fd);
}
readPidFile(void)
{
FILE *pid_fp = NULL;
- const char *f = NULL;
+ const char *f = Config.pidFilename;
pid_t pid = -1;
int i;
- if ((f = Config.pidFilename) == NULL || !strcmp(Config.pidFilename, "none")) {
+ if (f == NULL || !strcmp(Config.pidFilename, "none")) {
fprintf(stderr, "%s: ERROR: No pid file name defined\n", appname);
exit(1);
}
xmemcpy(&s.s_addr, hp->h_addr, sizeof(s.s_addr));
return s;
}
+double
+doubleAverage(double cur, double new, int n, int max)
+{
+ if (n > max)
+ n = max;
+ return (cur * (n - 1)) + new / n;
+}
+
+int
+intAverage(int cur, int new, int n, int max)
+{
+ if (n > max)
+ n = max;
+ return (cur * (n - 1)) + new / n;
+}