]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/adaptation/Initiate.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / adaptation / Initiate.cc
index cc123063993b81f48ca25606aea46c62c482b45b..0187e3d79302a429ba3b77c8fe3d444da68d1a3f 100644 (file)
@@ -1,41 +1,46 @@
 /*
- * DEBUG: section 93  ICAP (RFC 3507) Client
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
+/* DEBUG: section 93    ICAP (RFC 3507) Client */
+
 #include "squid.h"
-#include "HttpMsg.h"
-#include "adaptation/Service.h"
-#include "adaptation/Initiator.h"
+#include "adaptation/Answer.h"
 #include "adaptation/Initiate.h"
+#include "adaptation/Initiator.h"
+#include "base/AsyncJobCalls.h"
+#include "http/Message.h"
 
 namespace Adaptation
 {
-
-// AdaptInitiator::noteAdaptionAnswer Dialer locks/unlocks the message in transit
-// TODO: replace HTTPMSGLOCK with general RefCounting and delete this class
-class AnswerDialer: public UnaryMemFunT<Initiator, HttpMsg*>
+typedef UnaryMemFunT<Initiator, Answer, const Answer &> AnswerDialer;
+/// Calls expectNoConsumption() if noteAdaptationAnswer async call is
+/// scheduled but never fired (e.g., because the HTTP transaction aborts).
+class AnswerCall: public AsyncCallT<AnswerDialer>
 {
 public:
-    typedef UnaryMemFunT<Initiator, HttpMsg*> Parent;
+    AnswerCall(const char *aName, const AnswerDialer &aDialer) :
+        AsyncCallT<AnswerDialer>(93, 5, aName, aDialer), fired(false) {}
+    virtual void fire() {
+        fired = true;
+        AsyncCallT<AnswerDialer>::fire();
+    }
+    virtual ~AnswerCall() {
+        if (!fired && dialer.arg1.message != NULL && dialer.arg1.message->body_pipe != NULL)
+            dialer.arg1.message->body_pipe->expectNoConsumption();
+    }
 
-    AnswerDialer(Initiator *obj, Parent::Method meth, HttpMsg *msg):
-            Parent(obj, meth, msg) { HTTPMSGLOCK(arg1); }
-    AnswerDialer(const AnswerDialer &d):
-            Parent(d) { HTTPMSGLOCK(arg1); }
-    virtual ~AnswerDialer() { HTTPMSGUNLOCK(arg1); }
+private:
+    bool fired; ///< whether we fired the call
 };
+}
 
-} // namespace Adaptation
-
-
-/* Initiate */
-
-Adaptation::Initiate::Initiate(const char *aTypeName,
-                               Initiator *anInitiator, ServicePointer aService):
-        AsyncJob(aTypeName), theInitiator(anInitiator), theService(aService)
+Adaptation::Initiate::Initiate(const char *aTypeName): AsyncJob(aTypeName)
 {
-    assert(theService != NULL);
-    assert(theInitiator);
 }
 
 Adaptation::Initiate::~Initiate()
@@ -45,12 +50,20 @@ Adaptation::Initiate::~Initiate()
     // can assert(!(wasStarted && theInitiator)).
 }
 
+void
+Adaptation::Initiate::initiator(const CbcPointer<Initiator> &i)
+{
+    Must(!theInitiator);
+    Must(i.valid());
+    theInitiator = i;
+}
+
 // internal cleanup
 void Adaptation::Initiate::swanSong()
 {
     debugs(93, 5, HERE << "swan sings" << status());
 
-    if (theInitiator) {
+    if (theInitiator.set()) {
         debugs(93, 3, HERE << "fatal failure; sending abort notification");
         tellQueryAborted(true); // final by default
     }
@@ -60,35 +73,20 @@ void Adaptation::Initiate::swanSong()
 
 void Adaptation::Initiate::clearInitiator()
 {
-    if (theInitiator)
-        theInitiator.clear();
+    theInitiator.clear();
 }
 
-void Adaptation::Initiate::sendAnswer(HttpMsg *msg)
+void Adaptation::Initiate::sendAnswer(const Answer &answer)
 {
-    assert(msg);
-    if (theInitiator.isThere()) {
-        CallJob(93, 5, __FILE__, __LINE__, "Initiator::noteAdaptAnswer",
-                AnswerDialer(theInitiator.ptr(), &Initiator::noteAdaptationAnswer, msg));
-    }
+    AsyncCall::Pointer call = new AnswerCall("Initiator::noteAdaptationAnswer",
+            AnswerDialer(theInitiator, &Initiator::noteAdaptationAnswer, answer));
+    ScheduleCallHere(call);
     clearInitiator();
 }
 
-
 void Adaptation::Initiate::tellQueryAborted(bool final)
 {
-    if (theInitiator.isThere()) {
-        CallJobHere1(93, 5, theInitiator.ptr(),
-                     Initiator::noteAdaptationQueryAbort, final);
-    }
-    clearInitiator();
-}
-
-Adaptation::Service &
-Adaptation::Initiate::service()
-{
-    assert(theService != NULL);
-    return *theService;
+    sendAnswer(Answer::Error(final));
 }
 
 const char *Adaptation::Initiate::status() const
@@ -96,56 +94,3 @@ const char *Adaptation::Initiate::status() const
     return AsyncJob::status(); // for now
 }
 
-
-/* InitiatorHolder */
-
-Adaptation::InitiatorHolder::InitiatorHolder(Initiator *anInitiator):
-        prime(0), cbdata(0)
-{
-    if (anInitiator) {
-        cbdata = cbdataReference(anInitiator->toCbdata());
-        prime = anInitiator;
-    }
-}
-
-Adaptation::InitiatorHolder::InitiatorHolder(const InitiatorHolder &anInitiator):
-        prime(0), cbdata(0)
-{
-    if (anInitiator != NULL && cbdataReferenceValid(anInitiator.cbdata)) {
-        cbdata = cbdataReference(anInitiator.cbdata);
-        prime = anInitiator.prime;
-    }
-}
-
-Adaptation::InitiatorHolder::~InitiatorHolder()
-{
-    clear();
-}
-
-void Adaptation::InitiatorHolder::clear()
-{
-    if (prime) {
-        prime = NULL;
-        cbdataReferenceDone(cbdata);
-    }
-}
-
-Adaptation::Initiator *Adaptation::InitiatorHolder::ptr()
-{
-    assert(isThere());
-    return prime;
-}
-
-bool
-Adaptation::InitiatorHolder::isThere()
-{
-    return prime && cbdataReferenceValid(cbdata);
-}
-
-// should not be used
-Adaptation::InitiatorHolder &
-Adaptation::InitiatorHolder::operator =(const InitiatorHolder &anInitiator)
-{
-    assert(false);
-    return *this;
-}