]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/base/AsyncCall.h
ba802879878e220341f9cb4ab222ad824cb72e6a
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_SRC_BASE_ASYNCCALL_H
10 #define SQUID_SRC_BASE_ASYNCCALL_H
12 #include "base/CodeContext.h"
13 #include "base/forward.h"
14 #include "base/InstanceId.h"
19 \defgroup AsynCallsAPI Async-Calls API
21 * A call is asynchronous if the caller proceeds after the call is made,
22 * and the callee receives the call during the next main loop iteration.
23 * Asynchronous calls help avoid nasty call-me-when-I-call-you loops
24 * that humans often have trouble understanding or implementing correctly.
26 * Asynchronous calls are currently implemented via Squid events. The call
27 * event stores the pointer to the callback function and cbdata-protected
28 * callback data. To call a method of an object, the method is wrapped
29 * in a method-specific, static callback function and the pointer to the
30 * object is passed to the wrapper. For the method call to be safe, the
31 * class must be cbdata-enabled.
33 * You do not have to use the macros below to make or receive asynchronous
34 * method calls, but they give you a uniform interface and handy call
40 class AsyncCall
: public RefCountable
43 using Pointer
= AsyncCallPointer
;
45 AsyncCall(int aDebugSection
, int aDebugLevel
, const char *aName
);
46 ~AsyncCall() override
;
48 void make(); // fire if we can; handles general call debugging
50 // can be called from canFire() for debugging; always returns false
51 bool cancel(const char *reason
);
53 bool canceled() const { return isCanceled
!= nullptr; }
55 virtual CallDialer
*getDialer() = 0;
57 void print(std::ostream
&os
);
59 /// remove us from the queue; we are head unless we are queued after prev
60 void dequeue(AsyncCall::Pointer
&head
, AsyncCall::Pointer
&prev
);
62 void setNext(AsyncCall::Pointer aNext
) {
66 AsyncCall::Pointer
&Next() {
71 const char *const name
;
73 /// what the callee is expected to work on
74 CodeContext::Pointer codeContext
;
76 const int debugSection
;
78 const InstanceId
<AsyncCall
> id
;
81 virtual bool canFire();
83 virtual void fire() = 0;
85 AsyncCall::Pointer theNext
; ///< for AsyncCallList and similar lists
88 const char *isCanceled
; // set to the cancellation reason by cancel()
90 // not implemented to prevent nil calls from being passed around and unknowingly scheduled, for now.
92 AsyncCall(const AsyncCall
&);
96 std::ostream
&operator <<(std::ostream
&os
, AsyncCall
&call
)
103 \ingroup AsyncCallAPI
104 * Interface for all async call dialers
110 virtual ~CallDialer() {}
112 // TODO: Add these for clarity when CommCbFunPtrCallT is gone
113 //virtual bool canDial(AsyncCall &call) = 0;
114 //virtual void dial(AsyncCall &call) = 0;
116 virtual void print(std::ostream
&os
) const = 0;
120 \ingroup AsyncCallAPI
121 * This template implements an AsyncCall using a specified Dialer class
123 template <class DialerClass
>
124 class AsyncCallT
: public AsyncCall
127 using Dialer
= DialerClass
;
129 AsyncCallT(int aDebugSection
, int aDebugLevel
, const char *aName
,
130 const Dialer
&aDialer
): AsyncCall(aDebugSection
, aDebugLevel
, aName
),
133 AsyncCallT(const AsyncCallT
<Dialer
> &o
):
134 AsyncCall(o
.debugSection
, o
.debugLevel
, o
.name
),
137 ~AsyncCallT() override
{}
139 CallDialer
*getDialer() override
{ return &dialer
; }
144 bool canFire() override
{
145 return AsyncCall::canFire() &&
146 dialer
.canDial(*this);
148 void fire() override
{ dialer
.dial(*this); }
151 AsyncCallT
& operator=(const AsyncCallT
&); // not defined. call assignments not permitted.
154 template <class Dialer
>
155 RefCount
< AsyncCallT
<Dialer
> >
156 asyncCall(int aDebugSection
, int aDebugLevel
, const char *aName
,
157 const Dialer
&aDialer
)
159 return new AsyncCallT
<Dialer
>(aDebugSection
, aDebugLevel
, aName
, aDialer
);
162 /** Call scheduling helper. Use ScheduleCallHere if you can. */
163 bool ScheduleCall(const char *fileName
, int fileLine
, const AsyncCall::Pointer
&);
165 /** Call scheduling helper. */
166 #define ScheduleCallHere(call) ScheduleCall(__FILE__, __LINE__, (call))
168 #endif /* SQUID_SRC_BASE_ASYNCCALL_H */