]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Author: Alex Rousskov <rousskov@squid-cache.org>
authorAmos Jeffries <squid3@treenet.co.nz>
Thu, 13 May 2010 06:16:33 +0000 (18:16 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Thu, 13 May 2010 06:16:33 +0000 (18:16 +1200)
Bug 2896: assertion failed: comm.cc:2063: !fd_table[fd].closing()

src/Server.cc
src/Server.h
src/ftp.cc
src/http.cc

index 1b7c820d2338f942a618bfe28c5b1dd40ef37390..6782881022695d4ebd849d79f945740705e42814 100644 (file)
@@ -36,6 +36,7 @@
 #include "base/TextException.h"
 #include "Server.h"
 #include "Store.h"
+#include "fde.h" /* for fd_table[fd].closing */
 #include "HttpRequest.h"
 #include "HttpReply.h"
 #include "errorpage.h"
@@ -393,18 +394,32 @@ ServerStateData::sentRequestBody(const CommIoCbParams &io)
         sendMoreRequestBody();
 }
 
+bool
+ServerStateData::canSend(int fd) const
+{
+    return fd >= 0 && !fd_table[fd].closing();
+}
+
 void
 ServerStateData::sendMoreRequestBody()
 {
     assert(requestBodySource != NULL);
     assert(!requestSender);
+
+    const int fd = dataDescriptor();
+
+    if (!canSend(fd)) {
+        debugs(9,3, HERE << "cannot send request body to closing FD " << fd);
+        return; // wait for the kid's close handler; TODO: assert(closer);
+    }
+
     MemBuf buf;
     if (requestBodySource->getMoreData(buf)) {
         debugs(9,3, HERE << "will write " << buf.contentSize() << " request body bytes");
         typedef CommCbMemFunT<ServerStateData, CommIoCbParams> Dialer;
         requestSender = asyncCall(93,3, "ServerStateData::sentRequestBody",
                                   Dialer(this, &ServerStateData::sentRequestBody));
-        comm_write_mbuf(dataDescriptor(), &buf, requestSender);
+        comm_write_mbuf(fd, &buf, requestSender);
     } else {
         debugs(9,3, HERE << "will wait for more request body bytes or eof");
         requestSender = NULL;
index cf6516ca1439918711dd1497dafbcfc8ee8615a1..27e722ab9d73accd47242dfde7e430406ad19b96 100644 (file)
@@ -128,6 +128,8 @@ protected:
     void handleRequestBodyProductionEnded();
     virtual void handleRequestBodyProducerAborted() = 0;
 
+    /// whether it is not too late to write to the server
+    bool canSend(int fd) const;
     // sending of the request body to the server
     void sendMoreRequestBody();
     // has body; kids overwrite to increment I/O stats counters
index eff4ddc7f6b7562183fa3c7d5b1e21791044951a..4cf5be59008405d78c7ba9c3c33e965e99df8cb9 100644 (file)
@@ -1521,6 +1521,12 @@ FtpStateData::writeCommand(const char *buf)
 
     ctrl.last_command = ebuf;
 
+    if (!canSend(ctrl.fd)) {
+        debugs(9, 2, HERE << "cannot send to closing ctrl FD " << ctrl.fd);
+        // TODO: assert(ctrl.closer != NULL);
+        return;
+    }
+
     typedef CommCbMemFunT<FtpStateData, CommIoCbParams> Dialer;
     AsyncCall::Pointer call = asyncCall(9, 5, "FtpStateData::ftpWriteCommandCallback",
                                         Dialer(this, &FtpStateData::ftpWriteCommandCallback));
index f7bcb458befb828e1d63aa60c51b19bbb21ea16f..b94b04bdfe26ffe92402aa243af8e77259d2d8d4 100644 (file)
@@ -1992,6 +1992,13 @@ HttpStateData::sendRequest()
     MemBuf mb;
 
     debugs(11, 5, "httpSendRequest: FD " << fd << ", request " << request << ", this " << this << ".");
+
+    if (!canSend(fd)) {
+        debugs(11,3, HERE << "cannot send request to closing FD " << fd);
+        assert(closeHandler != NULL);
+        return false;
+    }
+
     typedef CommCbMemFunT<HttpStateData, CommTimeoutCbParams> TimeoutDialer;
     AsyncCall::Pointer timeoutCall =  asyncCall(11, 5, "HttpStateData::httpTimeout",
                                       TimeoutDialer(this,&HttpStateData::httpTimeout));
@@ -2095,6 +2102,13 @@ HttpStateData::doneSendingRequestBody()
             sendComplete(io);
         } else {
             debugs(11, 2, "doneSendingRequestBody: matched brokenPosts");
+
+           if (!canSend(fd)) {
+               debugs(11,2, HERE << "cannot send CRLF to closing FD " << fd);
+               assert(closeHandler != NULL);
+               return;
+            }
+
             typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
             Dialer dialer(this, &HttpStateData::sendComplete);
             AsyncCall::Pointer call= asyncCall(11,5, "HttpStateData::SendComplete", dialer);