From: wessels <> Date: Thu, 12 Sep 1996 22:39:53 +0000 (+0000) Subject: - Cleaned up gopher.c; prototypes, make functions static, etc. X-Git-Tag: SQUID_3_0_PRE1~5823 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56fa4cadbbb17eb8986b36f081f03e6ae766ab44;p=thirdparty%2Fsquid.git - Cleaned up gopher.c; prototypes, make functions static, etc. - Added READ_DEFERRED entry flag. Only extend lifetime when first entering deferred mode. --- diff --git a/src/ftp.cc b/src/ftp.cc index 0d5b783695..c7930b79da 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.53 1996/09/05 19:02:55 wessels Exp $ + * $Id: ftp.cc,v 1.54 1996/09/12 16:39:53 wessels Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -315,10 +315,15 @@ int ftpReadReply(fd, data) COMM_SELECT_READ, (PF) ftpReadReply, (void *) data); - /* NOTE there is no read timeout handler to disable */ + if (!BIT_TEST(entry->flag, READ_DEFERRED)) { + /* NOTE there is no read timeout handler to disable */ + BIT_SET(entry->flag, READ_DEFERRED); + } /* dont try reading again for a while */ comm_set_stall(fd, Config.stallDelay); return 0; + } else { + BIT_RESET(entry->flag, READ_DEFERRED); } errno = 0; len = read(fd, buf, SQUID_TCP_SO_RCVBUF); diff --git a/src/gopher.cc b/src/gopher.cc index e3c9ccc148..4ec917f006 100644 --- a/src/gopher.cc +++ b/src/gopher.cc @@ -1,5 +1,5 @@ /* - * $Id: gopher.cc,v 1.41 1996/09/03 19:24:02 wessels Exp $ + * $Id: gopher.cc,v 1.42 1996/09/12 16:39:53 wessels Exp $ * * DEBUG: section 10 Gopher * AUTHOR: Harvest Derived @@ -156,16 +156,35 @@ typedef struct gopher_ds { int cso_recno; int len; char *buf; /* pts to a 4k page */ -} GopherData; - -GopherData *CreateGopherData(); - -char def_gopher_bin[] = "www/unknown"; -char def_gopher_text[] = "text/plain"; +} GopherStateData; + +static int gopherStateFree _PARAMS((int fd, GopherStateData *)); +static void gopher_mime_content _PARAMS((char *buf, char *name, char *def)); +static void gopherMimeCreate _PARAMS((GopherStateData *)); +static int gopher_url_parser _PARAMS((char *url, + char *host, + int *port, + char *type_id, + char *request)); +static void gopherEndHTML _PARAMS((GopherStateData *)); +static void gopherToHTML _PARAMS((GopherStateData *, char *inbuf, int len)); +static int gopherReadReplyTimeout _PARAMS((int fd, GopherStateData *)); +static void gopherLifetimeExpire _PARAMS((int fd, GopherStateData *)); +static void gopherReadReply _PARAMS((int fd, GopherStateData *)); +static void gopherSendComplete _PARAMS((int fd, + char *buf, + int size, + int errflag, + void *data)); +static void gopherSendRequest _PARAMS((int fd, GopherStateData *)); +static GopherStateData *CreateGopherStateData _PARAMS((void)); + +static char def_gopher_bin[] = "www/unknown"; +static char def_gopher_text[] = "text/plain"; static int gopherStateFree(fd, gopherState) int fd; - GopherData *gopherState; + GopherStateData *gopherState; { if (gopherState == NULL) return 1; @@ -230,8 +249,8 @@ static void gopher_mime_content(buf, name, def) /* create MIME Header for Gopher Data */ -void gopherMimeCreate(data) - GopherData *data; +static void gopherMimeCreate(data) + GopherStateData *data; { LOCAL_ARRAY(char, tempMIME, MAX_MIME); @@ -281,7 +300,7 @@ MIME-version: 1.0\r\n", version_string); } /* Parse a gopher url into components. By Anawat. */ -int gopher_url_parser(url, host, port, type_id, request) +static int gopher_url_parser(url, host, port, type_id, request) char *url; char *host; int *port; @@ -321,15 +340,16 @@ int gopher_url_parser(url, host, port, type_id, request) int gopherCachable(url) char *url; { - GopherData *data = NULL; + GopherStateData *data = NULL; int cachable = 1; - /* use as temp data structure to parse gopher URL */ - data = CreateGopherData(); - + data = CreateGopherStateData(); /* parse to see type */ - gopher_url_parser(url, data->host, &data->port, &data->type_id, data->request); - + gopher_url_parser(url, + data->host, + &data->port, + &data->type_id, + data->request); switch (data->type_id) { case GOPHER_INDEX: case GOPHER_CSO: @@ -341,12 +361,11 @@ int gopherCachable(url) cachable = 1; } gopherStateFree(-1, data); - return cachable; } -void gopherEndHTML(data) - GopherData *data; +static void gopherEndHTML(data) + GopherStateData *data; { LOCAL_ARRAY(char, tmpbuf, TEMP_BUF_SIZE); @@ -361,8 +380,8 @@ void gopherEndHTML(data) /* Convert Gopher to HTML */ /* Borrow part of code from libwww2 came with Mosaic distribution */ -void gopherToHTML(data, inbuf, len) - GopherData *data; +static void gopherToHTML(data, inbuf, len) + GopherStateData *data; char *inbuf; int len; { @@ -663,10 +682,9 @@ void gopherToHTML(data, inbuf, len) return; } - -int gopherReadReplyTimeout(fd, data) +static int gopherReadReplyTimeout(fd, data) int fd; - GopherData *data; + GopherStateData *data; { StoreEntry *entry = NULL; entry = data->entry; @@ -677,9 +695,9 @@ int gopherReadReplyTimeout(fd, data) } /* This will be called when socket lifetime is expired. */ -void gopherLifetimeExpire(fd, data) +static void gopherLifetimeExpire(fd, data) int fd; - GopherData *data; + GopherStateData *data; { StoreEntry *entry = NULL; entry = data->entry; @@ -697,63 +715,84 @@ void gopherLifetimeExpire(fd, data) /* This will be called when data is ready to be read from fd. Read until * error or connection closed. */ -int gopherReadReply(fd, data) +static void gopherReadReply(fd, data) int fd; - GopherData *data; + GopherStateData *data; { char *buf = NULL; int len; int clen; int off; StoreEntry *entry = NULL; + int bin; entry = data->entry; - if (entry->flag & DELETE_BEHIND) { - if (storeClientWaiting(entry)) { - clen = entry->mem_obj->e_current_len; - off = entry->mem_obj->e_lowest_offset; - if ((clen - off) > GOPHER_DELETE_GAP) { - 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. */ - comm_set_select_handler(fd, - COMM_SELECT_READ, - (PF) gopherReadReply, - (void *) data); - /* don't install read timeout until we are below the GAP */ - comm_set_select_handler_plus_timeout(fd, - COMM_SELECT_TIMEOUT, - (PF) NULL, - (void *) NULL, - (time_t) 0); - comm_set_stall(fd, Config.stallDelay); /* dont try reading again for a while */ - return 0; - } - } else { - /* we can terminate connection right now */ - squid_error_entry(entry, ERR_NO_CLIENTS_BIG_OBJ, NULL); + if (entry->flag & DELETE_BEHIND && !storeClientWaiting(entry)) { + /* we can terminate connection right now */ + squid_error_entry(entry, ERR_NO_CLIENTS_BIG_OBJ, NULL); + comm_close(fd); + return; + } + /* check if we want to defer reading */ + clen = entry->mem_obj->e_current_len; + off = storeGetLowestReaderOffset(entry); + if ((clen - off) > GOPHER_DELETE_GAP) { + if (entry->flag & CLIENT_ABORT_REQUEST) { + squid_error_entry(entry, ERR_CLIENT_ABORT, NULL); comm_close(fd); - return 0; + return; + } + 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. */ + comm_set_select_handler(fd, + COMM_SELECT_READ, + (PF) gopherReadReply, + (void *) data); + /* don't install read timeout until we are below the GAP */ + comm_set_select_handler_plus_timeout(fd, + COMM_SELECT_TIMEOUT, + (PF) NULL, + (void *) NULL, + (time_t) 0); + if (!BIT_TEST(entry->flag, READ_DEFERRED)) { + comm_set_fd_lifetime(fd, 3600); /* limit during deferring */ + BIT_SET(entry->flag, READ_DEFERRED); } + /* dont try reading again for a while */ + comm_set_stall(fd, Config.stallDelay); + return; + } else { + BIT_RESET(entry->flag, READ_DEFERRED); } buf = get_free_4k_page(); errno = 0; - len = read(fd, buf, TEMP_BUF_SIZE - 1); /* leave one space for \0 in gopherToHTML */ + /* leave one space for \0 in gopherToHTML */ + len = read(fd, buf, TEMP_BUF_SIZE - 1); debug(10, 5, "gopherReadReply: FD %d read len=%d\n", fd, len); - + if (len > 0) { + IOStats.Gopher.reads++; + for (clen = len - 1, bin = 0; clen; bin++) + clen >>= 1; + IOStats.Gopher.read_hist[bin]++; + } if (len < 0) { debug(10, 1, "gopherReadReply: error reading: %s\n", xstrerror()); if (errno == EAGAIN || errno == EWOULDBLOCK) { /* reinstall handlers */ /* XXX This may loop forever */ - comm_set_select_handler(fd, COMM_SELECT_READ, - (PF) gopherReadReply, (void *) data); - comm_set_select_handler_plus_timeout(fd, COMM_SELECT_TIMEOUT, - (PF) gopherReadReplyTimeout, (void *) data, Config.readTimeout); + comm_set_select_handler(fd, + COMM_SELECT_READ, + (PF) gopherReadReply, + (void *) data); + comm_set_select_handler_plus_timeout(fd, + COMM_SELECT_TIMEOUT, + (PF) gopherReadReplyTimeout, + (void *) data, + Config.readTimeout); } else { BIT_RESET(entry->flag, ENTRY_CACHABLE); storeReleaseRequest(entry); @@ -779,7 +818,6 @@ int gopherReadReply(fd, data) !(entry->flag & DELETE_BEHIND)) { /* accept data, but start to delete behind it */ storeStartDeleteBehind(entry); - if (data->conversion != NORMAL) { gopherToHTML(data, buf, len); } else { @@ -823,19 +861,19 @@ int gopherReadReply(fd, data) Config.readTimeout); } put_free_4k_page(buf); - return 0; + return; } /* This will be called when request write is complete. Schedule read of * reply. */ -void gopherSendComplete(fd, buf, size, errflag, data) +static void gopherSendComplete(fd, buf, size, errflag, data) int fd; char *buf; int size; int errflag; void *data; { - GopherData *gopherState = (GopherData *) data; + GopherStateData *gopherState = (GopherStateData *) data; StoreEntry *entry = NULL; entry = gopherState->entry; debug(10, 5, "gopherSendComplete: FD %d size: %d errflag: %d\n", @@ -901,9 +939,9 @@ void gopherSendComplete(fd, buf, size, errflag, data) } /* This will be called when connect completes. Write request. */ -void gopherSendRequest(fd, data) +static void gopherSendRequest(fd, data) int fd; - GopherData *data; + GopherStateData *data; { int len; LOCAL_ARRAY(char, query, MAX_URL); @@ -944,7 +982,7 @@ int gopherStart(unusedfd, url, entry) { /* Create state structure. */ int sock, status; - GopherData *data = CreateGopherData(); + GopherStateData *data = CreateGopherStateData(); storeLockObject(data->entry = entry, NULL, NULL); @@ -1024,9 +1062,9 @@ int gopherStart(unusedfd, url, entry) } -GopherData *CreateGopherData() +static GopherStateData *CreateGopherStateData() { - GopherData *gd = xcalloc(1, sizeof(GopherData)); + GopherStateData *gd = xcalloc(1, sizeof(GopherStateData)); gd->buf = get_free_4k_page(); return (gd); } diff --git a/src/http.cc b/src/http.cc index afb62e47f7..139b24031d 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,5 +1,5 @@ /* - * $Id: http.cc,v 1.72 1996/09/05 19:02:56 wessels Exp $ + * $Id: http.cc,v 1.73 1996/09/12 16:39:54 wessels Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -436,10 +436,15 @@ static void httpReadReply(fd, httpState) (PF) NULL, (void *) NULL, (time_t) 0); - comm_set_fd_lifetime(fd, 3600); /* limit during deferring */ + if (!BIT_TEST(entry->flag, READ_DEFERRED)) { + comm_set_fd_lifetime(fd, 3600); /* limit during deferring */ + BIT_SET(entry->flag, READ_DEFERRED); + } /* dont try reading again for a while */ comm_set_stall(fd, Config.stallDelay); return; + } else { + BIT_RESET(entry->flag, READ_DEFERRED); } errno = 0; len = read(fd, buf, SQUID_TCP_SO_RCVBUF); diff --git a/src/stat.cc b/src/stat.cc index c478566e93..c7116dc44a 100644 --- a/src/stat.cc +++ b/src/stat.cc @@ -1,5 +1,5 @@ /* - * $Id: stat.cc,v 1.60 1996/09/05 22:16:00 wessels Exp $ + * $Id: stat.cc,v 1.61 1996/09/12 16:39:55 wessels Exp $ * * DEBUG: section 18 Cache Manager Statistics * AUTHOR: Harvest Derived @@ -236,6 +236,36 @@ void stat_io_get(sentry) percent(IOStats.Ftp.read_hist[i], IOStats.Ftp.reads)); } + storeAppendPrintf(sentry, "{}\n"); + storeAppendPrintf(sentry, "{Gopher I/O}\n"); + storeAppendPrintf(sentry, "{number of reads: %d}\n", IOStats.Gopher.reads); + storeAppendPrintf(sentry, "{deferred reads: %d (%d%%)}\n", + IOStats.Gopher.reads_deferred, + percent(IOStats.Gopher.reads_deferred, IOStats.Gopher.reads)); + storeAppendPrintf(sentry, "{Read Histogram:}\n"); + for (i = 0; i < 16; i++) { + storeAppendPrintf(sentry, "{%5d-%5d: %9d %2d%%}\n", + i ? (1 << (i - 1)) + 1 : 1, + 1 << i, + IOStats.Gopher.read_hist[i], + percent(IOStats.Gopher.read_hist[i], IOStats.Gopher.reads)); + } + + storeAppendPrintf(sentry, "{}\n"); + storeAppendPrintf(sentry, "{WAIS I/O}\n"); + storeAppendPrintf(sentry, "{number of reads: %d}\n", IOStats.Wais.reads); + storeAppendPrintf(sentry, "{deferred reads: %d (%d%%)}\n", + IOStats.Wais.reads_deferred, + percent(IOStats.Wais.reads_deferred, IOStats.Wais.reads)); + storeAppendPrintf(sentry, "{Read Histogram:}\n"); + for (i = 0; i < 16; i++) { + storeAppendPrintf(sentry, "{%5d-%5d: %9d %2d%%}\n", + i ? (1 << (i - 1)) + 1 : 1, + 1 << i, + IOStats.Wais.read_hist[i], + percent(IOStats.Wais.read_hist[i], IOStats.Wais.reads)); + } + storeAppendPrintf(sentry, close_bracket); } diff --git a/src/wais.cc b/src/wais.cc index d12330c71b..d49a0886eb 100644 --- a/src/wais.cc +++ b/src/wais.cc @@ -1,6 +1,6 @@ /* - * $Id: wais.cc,v 1.37 1996/09/03 19:24:09 wessels Exp $ + * $Id: wais.cc,v 1.38 1996/09/12 16:39:57 wessels Exp $ * * DEBUG: section 24 WAIS Relay * AUTHOR: Harvest Derived @@ -168,7 +168,6 @@ static void waisLifetimeExpire(fd, waisState) - /* This will be called when data is ready to be read from fd. Read until * error or connection closed. */ static void waisReadReply(fd, waisState) @@ -178,44 +177,60 @@ static void waisReadReply(fd, waisState) LOCAL_ARRAY(char, buf, 4096); int len; StoreEntry *entry = NULL; + int clen; + int off; + int bin; entry = waisState->entry; - if (entry->flag & DELETE_BEHIND) { - if (storeClientWaiting(entry)) { - /* check if we want to defer reading */ - if ((entry->mem_obj->e_current_len - - entry->mem_obj->e_lowest_offset) > WAIS_DELETE_GAP) { - debug(24, 3, "waisReadReply: Read deferred for Object: %s\n", - entry->url); - debug(24, 3, " Current Gap: %d bytes\n", - entry->mem_obj->e_current_len - - entry->mem_obj->e_lowest_offset); - /* reschedule, so it will automatically reactivated - * when Gap is big enough. */ - comm_set_select_handler(fd, - COMM_SELECT_READ, - (PF) waisReadReply, - (void *) waisState); - /* don't install read handler while we're above the gap */ - comm_set_select_handler_plus_timeout(fd, - COMM_SELECT_TIMEOUT, - (PF) NULL, - (void *) NULL, - (time_t) 0); - /* dont try reading again for a while */ - comm_set_stall(fd, Config.stallDelay); - return; - } - } else { - /* we can terminate connection right now */ - squid_error_entry(entry, ERR_NO_CLIENTS_BIG_OBJ, NULL); + if (entry->flag & DELETE_BEHIND && !storeClientWaiting(entry)) { + /* we can terminate connection right now */ + squid_error_entry(entry, ERR_NO_CLIENTS_BIG_OBJ, NULL); + comm_close(fd); + return; + } + /* check if we want to defer reading */ + clen = entry->mem_obj->e_current_len; + off = storeGetLowestReaderOffset(entry); + if ((clen - off) > WAIS_DELETE_GAP) { + if (entry->flag & CLIENT_ABORT_REQUEST) { + squid_error_entry(entry, ERR_CLIENT_ABORT, NULL); comm_close(fd); return; } + 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. */ + comm_set_select_handler(fd, + COMM_SELECT_READ, + (PF) waisReadReply, + (void *) waisState); + /* don't install read handler while we're above the gap */ + comm_set_select_handler_plus_timeout(fd, + COMM_SELECT_TIMEOUT, + (PF) NULL, + (void *) NULL, + (time_t) 0); + if (!BIT_TEST(entry->flag, READ_DEFERRED)) { + comm_set_fd_lifetime(fd, 3600); /* limit during deferring */ + BIT_SET(entry->flag, READ_DEFERRED); + } + /* dont try reading again for a while */ + comm_set_stall(fd, Config.stallDelay); + return; + } else { + BIT_RESET(entry->flag, READ_DEFERRED); } len = read(fd, buf, 4096); - debug(24, 5, "waisReadReply - fd: %d read len:%d\n", fd, len); - + debug(24, 5, "waisReadReply: FD %d read len:%d\n", fd, len); + if (len > 0) { + IOStats.Wais.reads++; + for (clen = len - 1, bin = 0; clen; bin++) + clen >>= 1; + IOStats.Wais.read_hist[bin]++; + } if (len < 0) { debug(24, 1, "waisReadReply: FD %d: read failure: %s.\n", xstrerror()); if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -281,7 +296,7 @@ static void waisSendComplete(fd, buf, size, errflag, data) StoreEntry *entry = NULL; WaisStateData *waisState = data; entry = waisState->entry; - debug(24, 5, "waisSendComplete - fd: %d size: %d errflag: %d\n", + debug(24, 5, "waisSendComplete: FD %d size: %d errflag: %d\n", fd, size, errflag); if (errflag) { squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); @@ -309,7 +324,7 @@ static void waisSendRequest(fd, waisState) char *buf = NULL; char *Method = RequestMethodStr[waisState->method]; - debug(24, 5, "waisSendRequest - fd: %d\n", fd); + debug(24, 5, "waisSendRequest: FD %d\n", fd); if (Method) len += strlen(Method); @@ -323,7 +338,7 @@ static void waisSendRequest(fd, waisState) waisState->mime_hdr); else sprintf(buf, "%s %s\r\n", Method, waisState->request); - debug(24, 6, "waisSendRequest - buf:%s\n", buf); + debug(24, 6, "waisSendRequest: buf: %s\n", buf); comm_write(fd, buf, len,