Amos Jeffries <[email protected]> writes:
> On 21/01/2013 9:21 a.m., Rainer Weikusat wrote:
>> The attached patch removes the timeout checking code from
>> ConnOpener::connect and
[...]
> the definitions of *F and *prt need to be inside their
> relevant if() scopes.
--- mad-squid-timeout/src/comm/ConnOpener.cc 8 Jan 2013 17:36:44 -0000 1.1.1.2
+++ mad-squid-timeout/src/comm/ConnOpener.cc 21 Jan 2013 16:48:02 -0000 1.1.1.2.6.4
@@ -242,16 +242,8 @@
switch (comm_connect_addr(temporaryFd_, conn_->remote) ) {
case COMM_INPROGRESS:
- // check for timeout FIRST.
- if (squid_curtime - connectStart_ > connectTimeout_) {
- debugs(5, 5, HERE << conn_ << ": * - ERR took too long already.");
- calls_.earlyAbort_->cancel("Comm::ConnOpener::connect timed out");
- doneConnecting(COMM_TIMEOUT, errno);
- return;
- } else {
- debugs(5, 5, HERE << conn_ << ": COMM_INPROGRESS");
- Comm::SetSelect(temporaryFd_, COMM_SELECT_WRITE, Comm::ConnOpener::InProgressConnectRetry, new Pointer(this), 0);
- }
+ debugs(5, 5, HERE << conn_ << ": COMM_INPROGRESS");
+ Comm::SetSelect(temporaryFd_, COMM_SELECT_WRITE, Comm::ConnOpener::InProgressConnectRetry, new Pointer(this), 0);
break;
case COMM_OK:
@@ -263,12 +255,7 @@
default:
++failRetries_;
- // check for timeout FIRST.
- if (squid_curtime - connectStart_ > connectTimeout_) {
- debugs(5, 5, HERE << conn_ << ": * - ERR took too long to receive response.");
- calls_.earlyAbort_->cancel("Comm::ConnOpener::connect timed out");
- doneConnecting(COMM_TIMEOUT, errno);
- } else if (failRetries_ < Config.connect_retries) {
+ if (failRetries_ < Config.connect_retries) {
debugs(5, 5, HERE << conn_ << ": * - try again");
eventAdd("Comm::ConnOpener::DelayedConnectRetry", Comm::ConnOpener::DelayedConnectRetry, new Pointer(this), 0.05, 0, false);
return;
@@ -319,7 +306,31 @@
void
Comm::ConnOpener::timeout(const CommTimeoutCbParams &)
{
- connect();
+ debugs(5, 5, HERE << conn_ << ": * - ERR took too long to receive response.");
+
+ if (temporaryFd_ >= 0) {
+ fde *F = &fd_table[temporaryFd_];
+ if (F->write_handler) {
+ // XXX: connect method installed a write handler
+ // after a successful non-blocking connect.
+ // Since this handler is not going to be called
+ // and Comm::SetSelect is not (yet) 'smart pointer
+ // aware', the Pointer object needs to be
+ // destroyed explicitly here to prevent the ConnOpener
+ // object from being leaked.
+ //
+ Pointer *ptr = static_cast<Pointer *>(F->write_data);
+ delete ptr;
+ F->write_data = NULL;
+ Comm::SetSelect(temporaryFd_, COMM_SELECT_WRITE, NULL, NULL, 0);
+ }
+
+ calls_.earlyAbort_->cancel("Comm::ConnOpener::connect timed out");
+ }
+
+ calls_.timeout_ = NULL;
+
+ doneConnecting(COMM_TIMEOUT, ETIMEDOUT);
}
/* Legacy Wrapper for the retry event after COMM_INPROGRESS