--------------------- PatchSet 4680 Date: 2007/06/01 20:47:07 Author: rousskov Branch: squid3-icap Tag: (none) Log: Bug #1981 fix: Tell FwdState that an unregistered and failed Server is gone. When a Server unregisters its fd (by calling FwdState::unregister) and then fails, call FwdState::handleUnregisteredServerEnd to tell FwdState that the server is done working, so that the transaction does not get stuck waiting for the server to call FwdState::complete. The old code would just set Server's FwdState pointer to NULL which was only enough if FwdState::self was already NULL due to aborts. This change fixed the bug in my limited ICAP tests. The whole FwdState relationship with Servers needs a serious revision as similar bugs probably do (or will) exist. We probably need to maintain a state variable representing the relationship. The following Server states are possible, at least: got valid FD and working, closed FD but still working, stopped working (failure or success). FwdState needs to be notified when we stopped working. Currently, when Server closes the FD, deep down the Server stack, it may not be clear whether the Server is still working or not. Finally, it may be a good idea for FwdState to notify Server when FwdState is aborted. Currently, the Server must check that the store entry is still valid to notice the abort, and it sometimes forgets to do that, causing store assertions. Members: src/forward.cc:1.39.2.10->1.39.2.11 src/forward.h:1.9.2.3->1.9.2.4 src/ftp.cc:1.29.2.20->1.29.2.21 src/http.cc:1.49.2.71->1.49.2.72 Index: squid3/src/forward.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/forward.cc,v retrieving revision 1.39.2.10 retrieving revision 1.39.2.11 diff -u -r1.39.2.10 -r1.39.2.11 --- squid3/src/forward.cc 22 May 2007 03:12:03 -0000 1.39.2.10 +++ squid3/src/forward.cc 1 Jun 2007 20:47:07 -0000 1.39.2.11 @@ -1,6 +1,6 @@ /* - * $Id: forward.cc,v 1.39.2.10 2007/05/22 03:12:03 rousskov Exp $ + * $Id: forward.cc,v 1.39.2.11 2007/06/01 20:47:07 rousskov Exp $ * * DEBUG: section 17 Request Forwarding * AUTHOR: Duane Wessels @@ -497,6 +497,17 @@ assert(server_fd == fd); server_fd = -1; + retryOrBail(); +} + +void +FwdState::retryOrBail() { + if (!self) { // we have aborted before the server called us back + debugs(17, 5, HERE << "not retrying because of earlier abort"); + // we will be destroyed when the server clears its Pointer to us + return; + } + if (checkRetry()) { int originserver = (servers->_peer == NULL); debugs(17, 3, "fwdServerClosed: re-forwarding (" << n_tries << " tries, " << (squid_curtime - start_t) << " secs)"); @@ -535,6 +546,16 @@ self = NULL; // refcounted } +// called by the server that failed after calling unregister() +void +FwdState::handleUnregisteredServerEnd() +{ + debugs(17, 2, "handleUnregisteredServerEnd: self=" << self << + " err=" << err << ' ' << entry->url()); + assert(server_fd < 0); + retryOrBail(); +} + #if USE_SSL void FwdState::negotiateSSL(int fd) Index: squid3/src/forward.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/forward.h,v retrieving revision 1.9.2.3 retrieving revision 1.9.2.4 diff -u -r1.9.2.3 -r1.9.2.4 --- squid3/src/forward.h 16 Apr 2007 19:47:45 -0000 1.9.2.3 +++ squid3/src/forward.h 1 Jun 2007 20:47:10 -0000 1.9.2.4 @@ -32,6 +32,7 @@ void fail(ErrorState *err); void unregister(int fd); void complete(); + void handleUnregisteredServerEnd(); int reforward(); bool reforwardableStatus(http_status s); void serverClosed(int fd); @@ -62,6 +63,7 @@ static void logReplyStatus(int tries, http_status status); void completed(); + void retryOrBail(); #if WIP_FWD_LOG Index: squid3/src/ftp.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/ftp.cc,v retrieving revision 1.29.2.20 retrieving revision 1.29.2.21 diff -u -r1.29.2.20 -r1.29.2.21 --- squid3/src/ftp.cc 22 May 2007 03:12:03 -0000 1.29.2.20 +++ squid3/src/ftp.cc 1 Jun 2007 20:47:12 -0000 1.29.2.21 @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.29.2.20 2007/05/22 03:12:03 rousskov Exp $ + * $Id: ftp.cc,v 1.29.2.21 2007/06/01 20:47:12 rousskov Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -3378,10 +3378,13 @@ { debugs(9,5,HERE << "aborting transaction for " << reason << "; FD " << ctrl.fd << ", Data FD " << data.fd << ", this " << this); - if (ctrl.fd >= 0) + if (ctrl.fd >= 0) { comm_close(ctrl.fd); - else - delete this; + return; + } + + fwd->handleUnregisteredServerEnd(); + delete this; } #if ICAP_CLIENT Index: squid3/src/http.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/http.cc,v retrieving revision 1.49.2.71 retrieving revision 1.49.2.72 diff -u -r1.49.2.71 -r1.49.2.72 --- squid3/src/http.cc 22 May 2007 03:12:03 -0000 1.49.2.71 +++ squid3/src/http.cc 1 Jun 2007 20:47:10 -0000 1.49.2.72 @@ -1,6 +1,6 @@ /* - * $Id: http.cc,v 1.49.2.71 2007/05/22 03:12:03 rousskov Exp $ + * $Id: http.cc,v 1.49.2.72 2007/06/01 20:47:10 rousskov Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -1923,10 +1923,13 @@ debugs(11,5, HERE << "aborting transaction for " << reason << "; FD " << fd << ", this " << this); - if (fd >= 0) + if (fd >= 0) { comm_close(fd); - else - delete this; + return; + } + + fwd->handleUnregisteredServerEnd(); + delete this; } void