]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Preserve caller context across tunnelDelayed*Read (#560)
authorEduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
Mon, 9 Mar 2020 18:11:12 +0000 (18:11 +0000)
committerAmos Jeffries <yadij@users.noreply.github.com>
Thu, 19 Mar 2020 10:49:01 +0000 (23:49 +1300)
tunnel.cc code approximates delay pools functionality using event.h API
that is not meant for transaction-specific events. We (temporary) add a
transaction context data member to TunnelStateData until the class
switches to using transaction-specific deferred reads API.

src/clients/HttpTunneler.cc
src/tunnel.cc

index 924d747ab94596623384b006c6a9c456b5633443..fe05eb61aac15df48ce654d2956692fb6c412d42 100644 (file)
@@ -206,6 +206,7 @@ Http::Tunneler::handleReadyRead(const CommIoCbParams &io)
 #else
     rd.size = readBuf.spaceSize();
 #endif
+    // XXX: defer read if rd.size <= 0
 
     switch (Comm::ReadNow(rd, readBuf)) {
     case Comm::INPROGRESS:
index 75e338d0ac5482b22341aada40ce8a2f70d086c2..16caef596db043d92f6b0bffdaff4929f0f1b65f 100644 (file)
@@ -168,6 +168,8 @@ public:
     HappyConnOpenerPointer connOpener; ///< current connection opening job
     ResolvedPeersPointer destinations; ///< paths for forwarding the request
     bool destinationsFound; ///< At least one candidate path found
+    // TODO: remove after fixing deferred reads in TunnelStateData::copyRead()
+    CodeContext::Pointer codeContext; ///< our creator context
 
     // AsyncCalls which we set and may need cancelling.
     struct {
@@ -318,7 +320,8 @@ TunnelStateData::TunnelStateData(ClientHttpRequest *clientRequest) :
     startTime(squid_curtime),
     waitingForConnectExchange(false),
     destinations(new ResolvedPeers()),
-    destinationsFound(false)
+    destinationsFound(false),
+    codeContext(CodeContext::Current())
 {
     debugs(26, 3, "TunnelStateData constructed this=" << this);
     client.readPendingFunc = &tunnelDelayedClientRead;
@@ -690,10 +693,13 @@ tunnelDelayedClientRead(void *data)
         return;
 
     TunnelStateData *tunnel = static_cast<TunnelStateData*>(data);
+    const auto savedContext = CodeContext::Current();
+    CodeContext::Reset(tunnel->codeContext);
     tunnel->client.readPending = NULL;
     static uint64_t counter=0;
     debugs(26, 7, "Client read(2) delayed " << ++counter << " times");
     tunnel->copyRead(tunnel->client, TunnelStateData::ReadClient);
+    CodeContext::Reset(savedContext);
 }
 
 static void
@@ -703,10 +709,13 @@ tunnelDelayedServerRead(void *data)
         return;
 
     TunnelStateData *tunnel = static_cast<TunnelStateData*>(data);
+    const auto savedContext = CodeContext::Current();
+    CodeContext::Reset(tunnel->codeContext);
     tunnel->server.readPending = NULL;
     static uint64_t counter=0;
     debugs(26, 7, "Server read(2) delayed " << ++counter << " times");
     tunnel->copyRead(tunnel->server, TunnelStateData::ReadServer);
+    CodeContext::Reset(savedContext);
 }
 
 void
@@ -717,6 +726,9 @@ TunnelStateData::copyRead(Connection &from, IOCB *completion)
     // then we schedule an event to try again in a few I/O cycles.
     // Allow at least 1 byte to be read every (0.3*10) seconds.
     int bw = from.bytesWanted(1, SQUID_TCP_SO_RCVBUF);
+    // XXX: Delay pools must not delay client-to-Squid traffic (i.e. when
+    // from.readPendingFunc is tunnelDelayedClientRead()).
+    // XXX: Bug #4913: Use DeferredRead instead.
     if (bw == 1 && ++from.delayedLoops < 10) {
         from.readPending = this;
         eventAdd("tunnelDelayedServerRead", from.readPendingFunc, from.readPending, 0.3, true);