From: Amos Jeffries Date: Thu, 13 May 2010 06:16:33 +0000 (+1200) Subject: Author: Alex Rousskov X-Git-Tag: SQUID_3_2_0_1~167^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=83aa23f92d470b4f829a42382eac2b75d41fbce4;p=thirdparty%2Fsquid.git Author: Alex Rousskov Bug 2896: assertion failed: comm.cc:2063: !fd_table[fd].closing() --- diff --git a/src/Server.cc b/src/Server.cc index 1b7c820d23..6782881022 100644 --- a/src/Server.cc +++ b/src/Server.cc @@ -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 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; diff --git a/src/Server.h b/src/Server.h index cf6516ca14..27e722ab9d 100644 --- a/src/Server.h +++ b/src/Server.h @@ -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 diff --git a/src/ftp.cc b/src/ftp.cc index eff4ddc7f6..4cf5be5900 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -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 Dialer; AsyncCall::Pointer call = asyncCall(9, 5, "FtpStateData::ftpWriteCommandCallback", Dialer(this, &FtpStateData::ftpWriteCommandCallback)); diff --git a/src/http.cc b/src/http.cc index f7bcb458be..b94b04bdfe 100644 --- a/src/http.cc +++ b/src/http.cc @@ -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 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 Dialer; Dialer dialer(this, &HttpStateData::sendComplete); AsyncCall::Pointer call= asyncCall(11,5, "HttpStateData::SendComplete", dialer);