=== modified file 'src/tunnel.cc' --- src/tunnel.cc 2011-04-03 12:17:09 +0000 +++ src/tunnel.cc 2011-04-05 11:11:48 +0000 @@ -38,6 +38,7 @@ #include "HttpRequest.h" #include "fde.h" #include "comm.h" +#include "comm/Loops.h" #include "comm/Write.h" #include "client_side_request.h" #include "acl/FilledChecklist.h" @@ -510,6 +511,27 @@ return; } + // client-side appears to have scheduled a read handler. make sure we dont collide with it. + if (COMMIO_FD_READCB(fd)->active()) { + Comm::IoCallback *ccb = COMMIO_FD_READCB(fd); + + // XXX: is this the right thing to do to client-side? + // for now it seems okay. tunnel closes the FD on completion for both success and fail. + // + // BUT in future when the tunnel traffic passes through client-side this may become broken. + // should we cancel the existing callback? and drop it? save for resuming later? + + debugs(26, 3, HERE << "switching client FD " << fd << " with callback " << ccb->callback << " to a tunnel."); + + // NP: avoid comm_read_cancel(fd, NULL, NULL) to state the CONNECT as reason for cancel + /* Delete the callback */ + ccb->callback->cancel("tunnelStateData assuming control of client FD"); + ccb->callback = NULL; + ccb->cancel("tunnelStateData assuming control of client FD"); + /* And the IO event */ + Comm::SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0); + } + if (cbdataReferenceValid(tunnelState)) { tunnelState->copyRead(tunnelState->server, TunnelStateData::ReadServer); tunnelState->copyRead(tunnelState->client, TunnelStateData::ReadClient);