]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/AsyncCall.cc
dc7f86e8b5a6cdd1e9d79d32b165934a02e1549f
[thirdparty/squid.git] / src / base / AsyncCall.cc
1 /*
2 * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #include "squid.h"
10 #include "base/AsyncCall.h"
11 #include "base/AsyncCallQueue.h"
12 #include "base/CodeContext.h"
13 #include "cbdata.h"
14 #include "Debug.h"
15 #include <ostream>
16
17 InstanceIdDefinitions(AsyncCall, "call");
18
19 /* AsyncCall */
20
21 AsyncCall::AsyncCall(int aDebugSection, int aDebugLevel, const char *aName):
22 name(aName),
23 codeContext(CodeContext::Current()),
24 debugSection(aDebugSection),
25 debugLevel(aDebugLevel),
26 theNext(nullptr),
27 isCanceled(nullptr)
28 {
29 debugs(debugSection, debugLevel, "The AsyncCall " << name << " constructed, this=" << this <<
30 " [" << id << ']');
31 }
32
33 AsyncCall::~AsyncCall()
34 {
35 assert(!theNext); // AsyncCallQueue must clean
36 }
37
38 void
39 AsyncCall::make()
40 {
41 debugs(debugSection, debugLevel, HERE << "make call " << name <<
42 " [" << id << ']');
43 if (canFire()) {
44 fire();
45 return;
46 }
47
48 if (!isCanceled) // we did not cancel() when returning false from canFire()
49 isCanceled = "unknown reason";
50
51 debugs(debugSection, debugLevel, HERE << "will not call " << name <<
52 " [" << id << ']' << " because of " << isCanceled);
53 }
54
55 bool
56 AsyncCall::cancel(const char *reason)
57 {
58 debugs(debugSection, debugLevel, HERE << "will not call " << name <<
59 " [" << id << "] " << (isCanceled ? "also " : "") <<
60 "because " << reason);
61
62 isCanceled = reason;
63 return false;
64 }
65
66 bool
67 AsyncCall::canFire()
68 {
69 return !isCanceled;
70 }
71
72 /// \todo make this method const by providing a const getDialer()
73 void
74 AsyncCall::print(std::ostream &os)
75 {
76 os << name;
77 if (const CallDialer *dialer = getDialer())
78 dialer->print(os);
79 else
80 os << "(?" << this << "?)";
81 }
82
83 void
84 AsyncCall::dequeue(AsyncCall::Pointer &head, AsyncCall::Pointer &prev)
85 {
86 if (prev != NULL)
87 prev->setNext(Next());
88 else
89 head = Next();
90 setNext(NULL);
91 }
92
93 bool
94 ScheduleCall(const char *fileName, int fileLine, AsyncCall::Pointer &call)
95 {
96 debugs(call->debugSection, call->debugLevel, fileName << "(" << fileLine <<
97 ") will call " << *call << " [" << call->id << ']' );
98
99 // Support callback creators that did not get their context from service A,
100 // but the current caller (service B) got that context from another source.
101 if (!call->codeContext)
102 call->codeContext = CodeContext::Current();
103
104 AsyncCallQueue::Instance().schedule(call);
105 return true;
106 }
107