From: wessels <> Date: Sat, 9 Jan 1999 04:12:06 +0000 (+0000) Subject: Moved storeAbort() call to store_client.c, where it really belongs X-Git-Tag: SQUID_3_0_PRE1~2447 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77b32a3490f29005f369bf956d5ea752c11d3806;p=thirdparty%2Fsquid.git Moved storeAbort() call to store_client.c, where it really belongs --- diff --git a/src/client_side.cc b/src/client_side.cc index c2506b223f..783efcf4ff 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.425 1998/12/09 23:00:58 wessels Exp $ + * $Id: client_side.cc,v 1.426 1999/01/08 21:12:06 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -64,10 +64,8 @@ static CWCB clientWriteComplete; static PF clientReadRequest; static PF connStateFree; static PF requestTimeout; -static int CheckQuickAbort2(const clientHttpRequest *); static int clientCheckTransferDone(clientHttpRequest *); static int clientGotNotEnough(clientHttpRequest *); -static void CheckQuickAbort(clientHttpRequest *); static void checkFailureRatio(err_type, hier_code); static void clientProcessMiss(clientHttpRequest *); static void clientBuildReplyHeader(clientHttpRequest * http, HttpReply * rep); @@ -373,37 +371,7 @@ clientHandleIMSReply(void *data, char *buf, ssize_t size) const http_status status = mem->reply->sline.status; debug(33, 3) ("clientHandleIMSReply: %s, %d bytes\n", url, (int) size); if (size < 0 && entry->store_status != STORE_ABORTED) -#if OLD_CODE - /* - * This storeAbort() call causes wrong behaviour in some situations. - * If there are multiple clients hanging on this entry, the second - * client will not want the entry to be aborted. This shows up in - * the stack trace below: - * - * #0 0xef5f452c in kill () - * #1 0xef5ba620 in abort () - * #2 0x7d680 in __eprintf (string=0x82a70 "%s:%u: failed assertion `%s'\n", expression=0x82a90 "client_side.c", line=1111, filename=0x83468 "size > 0") - * #3 0x2ad7c in clientCacheHit (data=0x31ae318, buf=0x17f1450 "", size=0) at client_side.c:1111 - * #4 0x65cd4 in storeClientCopy2 (e=0x4c48c0, sc=0x2eedd70) at store_client.c:264 - * #5 0x665b0 in InvokeHandlers (e=0x4c48c0) at store_client.c:510 - * #6 0x63c90 in storeAbort (e=0x4c48c0, cbflag=1) at store.c:626 - * #7 0x29190 in clientHandleIMSReply (data=0x31e9518, buf=0x2268810 "", size=-1) at client_side.c:343 - * #8 0x66450 in storeUnregister (e=0x2910c, data=0x31e9518) at store_client.c:467 - * #9 0x29a54 in httpRequestFree (data=0x31e9518) at client_side.c:579 - * #10 0x29eb4 in connStateFree (fd=534528, data=0x314d0d0) at client_side.c:667 - * #11 0x2f27c in commCallCloseHandlers (fd=42) at comm.c:501 - * #12 0x2f410 in comm_close (fd=42) at comm.c:565 - * #13 0x2d054 in clientReadRequest (fd=42, data=0x314d0d0) at client_side.c:2038 - * #14 0x309c8 in comm_poll (msec=434) at comm_select.c:354 - * #15 0x4da64 in main (argc=5, argv=0xeffffd4c) at main.c:587 - */ - storeAbort(entry, 1); -#endif - /* - * Lets just try to return here and see what kind of problems that - * causes - */ - return; + return; if (entry->store_status == STORE_ABORTED) { debug(33, 3) ("clientHandleIMSReply: ABORTED '%s'\n", url); /* We have an existing entry, but failed to validate it */ @@ -640,8 +608,7 @@ httpRequestFree(void *data) debug(33, 3) ("httpRequestFree: %s\n", storeUrl(entry)); if (!clientCheckTransferDone(http)) { if (entry) - storeUnregister(entry, http); /* unregister BEFORE abort */ - CheckQuickAbort(http); + storeUnregister(entry, http); entry = http->entry; /* reset, IMS might have changed it */ if (entry && entry->ping_status == PING_WAITING) storeReleaseRequest(entry); @@ -2471,64 +2438,6 @@ httpAccept(int sock, void *data) } } -/* return 1 if the request should be aborted */ -static int -CheckQuickAbort2(const clientHttpRequest * http) -{ - int curlen; - int minlen; - int expectlen; - - if (!http->request->flags.cachable) - return 1; - if (EBIT_TEST(http->entry->flags, KEY_PRIVATE)) - return 1; - if (http->entry->mem_obj == NULL) - return 1; - expectlen = http->entry->mem_obj->reply->content_length; - curlen = (int) http->entry->mem_obj->inmem_hi; - minlen = (int) Config.quickAbort.min << 10; - if (minlen < 0) - /* disabled */ - return 0; - if (curlen > expectlen) - /* bad content length */ - return 1; - if ((expectlen - curlen) < minlen) - /* only little more left */ - return 0; - if ((expectlen - curlen) > (Config.quickAbort.max << 10)) - /* too much left to go */ - return 1; - if (expectlen < 100) - /* avoid FPE */ - return 0; - if ((curlen / (expectlen / 100)) > Config.quickAbort.pct) - /* past point of no return */ - return 0; - return 1; -} - - -static void -CheckQuickAbort(clientHttpRequest * http) -{ - StoreEntry *entry = http->entry; - /* Note, set entry here because http->entry might get changed (for IMS - * requests) during the storeAbort() call */ - if (entry == NULL) - return; - if (storePendingNClients(entry) > 0) - return; - if (entry->store_status != STORE_PENDING) - return; - if (CheckQuickAbort2(http) == 0) - return; - debug(33, 3) ("CheckQuickAbort: ABORTING %s\n", storeUrl(entry)); - Counter.aborted_requests++; - storeAbort(entry, 1); -} - #define SENDING_BODY 0 #define SENDING_HDRSONLY 1 static int diff --git a/src/comm.cc b/src/comm.cc index 5944c4c48c..cb242836e1 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,6 +1,6 @@ /* - * $Id: comm.cc,v 1.293 1998/12/05 00:54:20 wessels Exp $ + * $Id: comm.cc,v 1.294 1999/01/08 21:12:08 wessels Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -545,6 +545,7 @@ comm_close(int fd) #if USE_ASYNC_IO int doaioclose = 1; #endif + extern int current_hdl_fd; debug(5, 5) ("comm_close: FD %d\n", fd); assert(fd >= 0); assert(fd < Squid_MaxFD); @@ -553,6 +554,10 @@ comm_close(int fd) return; if (shutting_down && (!F->open || F->type == FD_FILE)) return; + if (fd == current_hdl_fd) { + F->flags.delayed_comm_close = 1; + return; + } assert(F->open); assert(F->type != FD_FILE); #ifdef USE_ASYNC_IO diff --git a/src/comm_select.cc b/src/comm_select.cc index 2d80096656..4e9766ec0c 100644 --- a/src/comm_select.cc +++ b/src/comm_select.cc @@ -1,6 +1,6 @@ /* - * $Id: comm_select.cc,v 1.23 1998/12/04 22:20:15 wessels Exp $ + * $Id: comm_select.cc,v 1.24 1999/01/08 21:12:09 wessels Exp $ * * DEBUG: section 5 Socket Functions * @@ -49,6 +49,8 @@ #define FD_MASK_BYTES sizeof(fd_mask) #define FD_MASK_BITS (FD_MASK_BYTES*NBBY) +/* GLOBAL */ +int current_hdl_fd = -1; /* STATIC */ #if !HAVE_POLL @@ -343,6 +345,7 @@ comm_poll(int msec) * more frequently to minimize losses due to the 5 connect * limit in SunOS */ for (i = 0; i < nfds; i++) { + fde *F; int revents; if (((revents = pfds[i].revents) == 0) || ((fd = pfds[i].fd) == -1)) continue; @@ -354,13 +357,18 @@ comm_poll(int msec) callhttp = 1; continue; } + F = &fd_table[fd]; if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { debug(5, 6) ("comm_poll: FD %d ready for reading\n", fd); - if ((hdl = fd_table[fd].read_handler)) { - fd_table[fd].read_handler = NULL; - hdl(fd, fd_table[fd].read_data); + if ((hdl = F->read_handler)) { + F->read_handler = NULL; + hdl(current_hdl_fd = fd, F->read_data); Counter.select_fds++; } + if (F->flags.delayed_comm_close) { + current_hdl_fd = -1; + comm_close(fd); + } if (commCheckICPIncoming) comm_poll_icp_incoming(); if (commCheckHTTPIncoming) @@ -368,11 +376,15 @@ comm_poll(int msec) } if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { debug(5, 5) ("comm_poll: FD %d ready for writing\n", fd); - if ((hdl = fd_table[fd].write_handler)) { - fd_table[fd].write_handler = NULL; - hdl(fd, fd_table[fd].write_data); + if ((hdl = F->write_handler)) { + F->write_handler = NULL; + hdl(current_hdl_fd = fd, F->write_data); Counter.select_fds++; } + if (F->flags.delayed_comm_close) { + current_hdl_fd = -1; + comm_close(fd); + } if (commCheckICPIncoming) comm_poll_icp_incoming(); if (commCheckHTTPIncoming) @@ -380,10 +392,9 @@ comm_poll(int msec) } if (revents & POLLNVAL) { close_handler *ch; - fde *F = &fd_table[fd]; debug(5, 0) ("WARNING: FD %d has handlers, but it's invalid.\n", fd); - debug(5, 0) ("FD %d is a %s\n", fd, fdTypeStr[fd_table[fd].type]); - debug(5, 0) ("--> %s\n", fd_table[fd].desc); + debug(5, 0) ("FD %d is a %s\n", fd, fdTypeStr[F->type]); + debug(5, 0) ("--> %s\n", F->desc); debug(5, 0) ("tmout:%p read:%p write:%p\n", F->timeout_handler, F->read_handler, @@ -551,6 +562,7 @@ comm_select(int msec) static time_t last_timeout = 0; struct timeval poll_time; double timeout = current_dtime + (msec / 1000.0); + fde *F; do { #if !ALARM_UPDATES_TIME getCurrentTime(); @@ -652,14 +664,19 @@ comm_select(int msec) callhttp = 1; continue; } + F = &fd_table[fd]; debug(5, 6) ("comm_select: FD %d ready for reading\n", fd); - if (fd_table[fd].read_handler) { - hdl = fd_table[fd].read_handler; - fd_table[fd].read_handler = NULL; + if (F->read_handler) { + hdl = F->read_handler; + F->read_handler = NULL; commUpdateReadBits(fd, NULL); - hdl(fd, fd_table[fd].read_data); + hdl(current_hdl_fd = fd, F->read_data); Counter.select_fds++; } + if (F->flags.delayed_comm_close) { + current_hdl_fd = -1; + comm_close(fd); + } if (commCheckICPIncoming) comm_select_icp_incoming(); if (commCheckHTTPIncoming) @@ -690,14 +707,19 @@ comm_select(int msec) callhttp = 1; continue; } + F = &fd_table[fd]; debug(5, 5) ("comm_select: FD %d ready for writing\n", fd); - if (fd_table[fd].write_handler) { - hdl = fd_table[fd].write_handler; - fd_table[fd].write_handler = NULL; + if (F->write_handler) { + hdl = F->write_handler; + F->write_handler = NULL; commUpdateWriteBits(fd, NULL); - hdl(fd, fd_table[fd].write_data); + hdl(current_hdl_fd = fd, F->write_data); Counter.select_fds++; } + if (F->flags.delayed_comm_close) { + current_hdl_fd = -1; + comm_close(fd); + } if (commCheckICPIncoming) comm_select_icp_incoming(); if (commCheckHTTPIncoming) @@ -774,7 +796,7 @@ examine_select(fd_set * readfds, fd_set * writefds) debug(5, 0) ("WARNING: FD %d has handlers, but it's invalid.\n", fd); debug(5, 0) ("FD %d is a %s called '%s'\n", fd, - fdTypeStr[fd_table[fd].type], + fdTypeStr[F->type], F->desc); debug(5, 0) ("tmout:%p read:%p write:%p\n", F->timeout_handler, diff --git a/src/forward.cc b/src/forward.cc index 5e3114d11d..800afd7863 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -1,6 +1,6 @@ /* - * $Id: forward.cc,v 1.40 1998/12/29 22:51:11 wessels Exp $ + * $Id: forward.cc,v 1.41 1999/01/08 21:12:10 wessels Exp $ * * DEBUG: section 17 Request Forwarding * AUTHOR: Duane Wessels @@ -87,8 +87,6 @@ fwdStateFree(FwdState * fwdState) err->request = requestLink(fwdState->request); err->xerrno = fwdState->fail.xerrno; errorAppendEntry(e, err); - } else { - storeAbort(e, 0); } } fwdServersFree(&fwdState->servers); @@ -193,8 +191,6 @@ fwdConnectTimeout(int fd, void *data) err = errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT); err->request = requestLink(fwdState->request); errorAppendEntry(entry, err); - } else { - storeAbort(entry, 0); } comm_close(fd); } @@ -498,7 +494,7 @@ fwdComplete(FwdState * fwdState) e->mem_obj->reply->sline.status); fwdLogReplyStatus(fwdState->n_tries, e->mem_obj->reply->sline.status); if (fwdReforward(fwdState)) { - debug(17, 1) ("fwdComplete: re-forwarding %d %s\n", + debug(17, 3) ("fwdComplete: re-forwarding %d %s\n", e->mem_obj->reply->sline.status, storeUrl(e)); if (fwdState->server_fd > -1) diff --git a/src/ftp.cc b/src/ftp.cc index 871ae1544f..340538afea 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.257 1998/12/05 00:54:25 wessels Exp $ + * $Id: ftp.cc,v 1.258 1999/01/08 21:12:11 wessels Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -323,8 +323,6 @@ ftpTimeout(int fd, void *data) err = errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT); err->request = requestLink(ftpState->request); errorAppendEntry(entry, err); - } else { - storeAbort(entry, 0); } } if (ftpState->data.fd > -1) { @@ -841,7 +839,6 @@ ftpDataRead(int fd, void *data) Config.Timeout.read); } else { assert(mem->inmem_hi > 0); - storeAbort(entry, 0); ftpDataTransferDone(ftpState); } } else if (len == 0) { @@ -1059,8 +1056,6 @@ ftpWriteCommandCallback(int fd, char *bufnotused, size_t size, int errflag, void err->request = requestLink(ftpState->request); errorAppendEntry(entry, err); } - if (entry->store_status == STORE_PENDING) - storeAbort(entry, 0); comm_close(ftpState->ctrl.fd); } } @@ -1176,8 +1171,6 @@ ftpReadControlReply(int fd, void *data) err->request = requestLink(ftpState->request); errorAppendEntry(entry, err); } - if (entry->store_status == STORE_PENDING) - storeAbort(entry, 0); comm_close(ftpState->ctrl.fd); } return; diff --git a/src/gopher.cc b/src/gopher.cc index b462b3c2b8..30b26dca8f 100644 --- a/src/gopher.cc +++ b/src/gopher.cc @@ -1,7 +1,7 @@ /* - * $Id: gopher.cc,v 1.141 1998/12/05 00:54:26 wessels Exp $ + * $Id: gopher.cc,v 1.142 1999/01/08 21:12:13 wessels Exp $ * * DEBUG: section 10 Gopher * AUTHOR: Harvest Derived @@ -580,8 +580,6 @@ gopherTimeout(int fd, void *data) err = errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT); err->url = xstrdup(gopherState->request); errorAppendEntry(entry, err); - } else { - storeAbort(entry, 0); } comm_close(fd); } @@ -638,7 +636,6 @@ gopherReadReply(int fd, void *data) errorAppendEntry(entry, err); comm_close(fd); } else { - storeAbort(entry, 0); comm_close(fd); } } else if (len == 0 && entry->mem_obj->inmem_hi == 0) { diff --git a/src/http.cc b/src/http.cc index d7fa31f1a0..2ed19a9366 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,6 +1,6 @@ /* - * $Id: http.cc,v 1.334 1998/12/11 23:10:47 wessels Exp $ + * $Id: http.cc,v 1.335 1999/01/08 21:12:14 wessels Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -93,8 +93,6 @@ httpTimeout(int fd, void *data) assert(entry->store_status == STORE_PENDING); if (entry->mem_obj->inmem_hi == 0) { fwdFail(httpState->fwd, ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT, 0); - } else { - storeAbort(entry, 0); } comm_close(fd); } @@ -473,7 +471,6 @@ httpReadReply(int fd, void *data) fwdFail(httpState->fwd, ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno); comm_close(fd); } else { - storeAbort(entry, 0); comm_close(fd); } } else if (len == 0 && entry->mem_obj->inmem_hi == 0) { diff --git a/src/store_client.cc b/src/store_client.cc index d37f4ae603..97aa29ba7b 100644 --- a/src/store_client.cc +++ b/src/store_client.cc @@ -1,6 +1,6 @@ /* - * $Id: store_client.cc,v 1.49 1998/12/05 00:54:44 wessels Exp $ + * $Id: store_client.cc,v 1.50 1999/01/08 21:12:16 wessels Exp $ * * DEBUG: section 20 Storage Manager Client-Side Interface * AUTHOR: Duane Wessels @@ -47,6 +47,8 @@ static void storeClientCopy2(StoreEntry * e, store_client * sc); static void storeClientFileRead(store_client * sc); static EVH storeClientCopyEvent; static store_client_t storeClientType(StoreEntry *); +static int CheckQuickAbort2(StoreEntry * entry); +static void CheckQuickAbort(StoreEntry * entry); /* check if there is any client waiting for this object at all */ /* return 1 if there is at least one client */ @@ -461,6 +463,9 @@ storeUnregister(StoreEntry * e, void *data) callback(sc->callback_data, sc->copy_buf, -1); } cbdataFree(sc); + assert(e->lock_count > 0); + if (mem->nclients == 0) + CheckQuickAbort(e); return 1; } @@ -513,3 +518,67 @@ storePendingNClients(const StoreEntry * e) debug(20, 3) ("storePendingNClients: returning %d\n", npend); return npend; } + +/* return 1 if the request should be aborted */ +static int +CheckQuickAbort2(StoreEntry * entry) +{ + int curlen; + int minlen; + int expectlen; + MemObject *mem = entry->mem_obj; + assert(mem); + debug(20, 3) ("CheckQuickAbort2: entry=%p, mem=%p\n", entry, mem); + if (!mem->request->flags.cachable) { + debug(20, 3) ("CheckQuickAbort2: YES !mem->request->flags.cachable\n"); + return 1; + } + if (EBIT_TEST(entry->flags, KEY_PRIVATE)) { + debug(20, 3) ("CheckQuickAbort2: YES KEY_PRIVATE\n"); + return 1; + } + expectlen = mem->reply->content_length; + curlen = (int) mem->inmem_hi; + minlen = (int) Config.quickAbort.min << 10; + if (minlen < 0) { + debug(20, 3) ("CheckQuickAbort2: NO disabled\n"); + return 0; + } + if (curlen > expectlen) { + debug(20, 3) ("CheckQuickAbort2: YES bad content length\n"); + return 1; + } + if ((expectlen - curlen) < minlen) { + debug(20, 3) ("CheckQuickAbort2: NO only little more left\n"); + return 0; + } + if ((expectlen - curlen) > (Config.quickAbort.max << 10)) { + debug(20, 3) ("CheckQuickAbort2: YES too much left to go\n"); + return 1; + } + if (expectlen < 100) { + debug(20, 3) ("CheckQuickAbort2: NO avoid FPE\n"); + return 0; + } + if ((curlen / (expectlen / 100)) > Config.quickAbort.pct) { + debug(20, 3) ("CheckQuickAbort2: NO past point of no return\n"); + return 0; + } + debug(20, 3) ("CheckQuickAbort2: YES default, returning 1\n"); + return 1; +} + +static void +CheckQuickAbort(StoreEntry * entry) +{ + if (entry == NULL) + return; + if (storePendingNClients(entry) > 0) + return; + if (entry->store_status != STORE_PENDING) + return; + if (CheckQuickAbort2(entry) == 0) + return; + Counter.aborted_requests++; + storeAbort(entry, 1); +} diff --git a/src/store_swapout.cc b/src/store_swapout.cc index 667cd436b8..6ce99cb29a 100644 --- a/src/store_swapout.cc +++ b/src/store_swapout.cc @@ -1,6 +1,6 @@ /* - * $Id: store_swapout.cc,v 1.39 1998/12/16 06:34:31 wessels Exp $ + * $Id: store_swapout.cc,v 1.40 1999/01/08 21:12:17 wessels Exp $ * * DEBUG: section 20 Storage Manager Swapout Functions * AUTHOR: Duane Wessels @@ -135,7 +135,8 @@ storeCheckSwapOut(StoreEntry * e) char *swap_buf; ssize_t swap_buf_len; int hdr_len = 0; - assert(mem != NULL); + if (mem == NULL) + return; /* should we swap something out to disk? */ debug(20, 7) ("storeCheckSwapOut: %s\n", storeUrl(e)); debug(20, 7) ("storeCheckSwapOut: store_status = %s\n", diff --git a/src/structs.h b/src/structs.h index 74ccd10ad7..f2f1e0ef34 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,7 +1,7 @@ /* - * $Id: structs.h,v 1.254 1998/12/15 17:33:58 wessels Exp $ + * $Id: structs.h,v 1.255 1999/01/08 21:12:18 wessels Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -508,6 +508,7 @@ struct _fde { #ifdef OPTIMISTIC_IO unsigned int calling_io_handler:1; #endif + unsigned int delayed_comm_close:1; } flags; int bytes_read; int bytes_written; diff --git a/src/whois.cc b/src/whois.cc index 37175f32f0..abb01d8998 100644 --- a/src/whois.cc +++ b/src/whois.cc @@ -1,5 +1,6 @@ + /* - * $Id: whois.cc,v 1.7 1998/12/05 00:54:49 wessels Exp $ + * $Id: whois.cc,v 1.8 1999/01/08 21:12:19 wessels Exp $ * * DEBUG: section 75 WHOIS protocol * AUTHOR: Duane Wessels, Kostas Anagnostakis @@ -106,7 +107,6 @@ whoisReadReply(int fd, void *data) fwdFail(p->fwd, ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno); comm_close(fd); } else { - storeAbort(entry, 0); comm_close(fd); } } else {