AsyncCallbacks.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 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#ifndef SQUID_SRC_BASE_ASYNCCALLBACKS_H
10#define SQUID_SRC_BASE_ASYNCCALLBACKS_H
11
12#include "base/AsyncCall.h"
13#include "base/AsyncJobCalls.h"
14#include "base/TypeTraits.h"
15
17template <typename AnswerT>
19{
20public:
21 using Answer = AnswerT;
22
23 virtual ~WithAnswer() = default;
24
26 virtual Answer &answer() = 0;
27};
28
30template <typename Answer>
32{
33public:
34 // all generated copying/moving functions are correct
35 AsyncCallback() = default;
36
37 template <class Call>
38 explicit AsyncCallback(const RefCount<Call> &call):
39 call_(call),
40 answer_(&(call->dialer.answer()))
41 {
42 }
43
44 Answer &answer()
45 {
47 return *answer_;
48 }
49
53 {
54 answer_ = nullptr;
55 const auto call = call_;
56 call_ = nullptr;
57 return call;
58 }
59
61 explicit operator bool() const { return answer_; }
62
63 /* methods for decaying into an AsyncCall pointer w/o access to answer */
64 operator const AsyncCall::Pointer &() const { return call_; }
65 const AsyncCall &operator *() const { return call_.operator*(); }
66 const AsyncCall *operator ->() const { return call_.operator->(); }
67
68private:
71
74 Answer *answer_ = nullptr;
75};
76
78template <typename Argument1>
80 public CallDialer,
81 public WithAnswer<Argument1>
82{
83public:
84 // stand-alone function that receives our answer
85 using Handler = void (Argument1 &);
86
87 explicit UnaryFunCallbackDialer(Handler * const aHandler): handler(aHandler) {}
88 ~UnaryFunCallbackDialer() override = default;
89
90 /* CallDialer API */
91 bool canDial(AsyncCall &) { return bool(handler); }
92 void dial(AsyncCall &) { handler(arg1); }
93 void print(std::ostream &os) const final { os << '(' << arg1 << ')'; }
94
95 /* WithAnswer API */
96 Argument1 &answer() final { return arg1; }
97
98private:
101};
102
105template <class Destination, typename Argument1>
107 public CallDialer,
108 public WithAnswer<Argument1>
109{
110public:
111 // class member function that receives our answer
112 typedef void (Destination::*Method)(Argument1 &);
113
114 UnaryCbcCallbackDialer(Method method, Destination *destination): destination_(destination), method_(method) {}
115 ~UnaryCbcCallbackDialer() override = default;
116
117 /* CallDialer API */
118 bool canDial(AsyncCall &) { return destination_.valid(); }
119 void dial(AsyncCall &) {((*destination_).*method_)(arg1_); }
120 void print(std::ostream &os) const final { os << '(' << arg1_ << ')'; }
121
122 /* WithAnswer API */
123 Argument1 &answer() final { return arg1_; }
124
125private:
129};
130
133template <class Job, typename Argument1>
135 public UnaryMemFunT<Job, Argument1, Argument1&>,
136 public WithAnswer<Argument1>
137{
138public:
140
142 Base(aJob, aMethod, {}) {}
143
144 /* WithAnswer API */
145 Argument1 &answer() final { return this->arg1; }
146};
147
150template <typename T>
151using IsAsyncJob = typename std::conditional<
152 std::is_base_of<AsyncJob, T>::value,
153 std::true_type,
154 std::false_type
155 >::type;
156
158template <class Destination, typename Argument1, std::enable_if_t<!IsAsyncJob<Destination>::value, int> = 0>
160callbackDialer(void (Destination::*method)(Argument1 &), Destination * const destination)
161{
162 static_assert(!std::is_base_of<AsyncJob, Destination>::value, "wrong wrapper");
163 return UnaryCbcCallbackDialer<Destination, Argument1>(method, destination);
164}
165
167template <class Destination, typename Argument1, std::enable_if_t<IsAsyncJob<Destination>::value, int> = 0>
169callbackDialer(void (Destination::*method)(Argument1 &), Destination * const destination)
170{
171 static_assert(std::is_base_of<AsyncJob, Destination>::value, "wrong wrapper");
172 return UnaryJobCallbackDialer<Destination, Argument1>(destination, method);
173}
174
176template <typename Argument1>
178callbackDialer(void (*destination)(Argument1 &))
179{
180 return UnaryFunCallbackDialer<Argument1>(destination);
181}
182
185template <class Call>
188{
190}
191
195#define asyncCallback(dbgSection, dbgLevel, method, object) \
196 AsyncCallback_(asyncCall((dbgSection), (dbgLevel), #method, \
197 callbackDialer(&method, (object))))
198
199// TODO: Use C++20 __VA_OPT__ to merge this with asyncCallback().
201#define asyncCallbackFun(dbgSection, dbgLevel, function) \
202 AsyncCallback_(asyncCall((dbgSection), (dbgLevel), #function, \
203 callbackDialer(&function)))
204
205#endif // SQUID_SRC_BASE_ASYNCCALLBACKS_H
206
typename std::conditional< std::is_base_of< AsyncJob, T >::value, std::true_type, std::false_type >::type IsAsyncJob
UnaryCbcCallbackDialer< Destination, Argument1 > callbackDialer(void(Destination::*method)(Argument1 &), Destination *const destination)
helper function to simplify UnaryCbcCallbackDialer creation
AsyncCallback< typename Call::Dialer::Answer > AsyncCallback_(const RefCount< Call > &call)
#define assert(EX)
Definition: assert.h:17
a smart AsyncCall pointer for delivery of future results
Answer * answer_
const AsyncCall & operator*() const
const AsyncCall * operator->() const
AsyncCall::Pointer release()
AsyncCall::Pointer call_
callback carrying the answer
Answer & answer()
AsyncCallback()=default
AsyncCallback(const RefCount< Call > &call)
Cbc * valid() const
was set and is valid
Definition: CbcPointer.h:41
void print(std::ostream &os) const final
~UnaryCbcCallbackDialer() override=default
UnaryCbcCallbackDialer(Method method, Destination *destination)
bool canDial(AsyncCall &)
void(Destination::* Method)(Argument1 &)
CbcPointer< Destination > destination_
object to deliver the answer to
void dial(AsyncCall &)
Method method_
Destination method to call with the answer.
Argument1 & answer() final
callback results setter
CallDialer for single-parameter callback functions.
void dial(AsyncCall &)
Argument1 arg1
actual call parameter
bool canDial(AsyncCall &)
Handler * handler
the function to call
~UnaryFunCallbackDialer() override=default
void print(std::ostream &os) const final
Argument1 & answer() final
callback results setter
void(Argument1 &) Handler
UnaryFunCallbackDialer(Handler *const aHandler)
UnaryJobCallbackDialer(const CbcPointer< Job > &aJob, typename Base::Method aMethod)
Argument1 & answer() final
callback results setter
access to a callback result carried by an asynchronous CallDialer
virtual Answer & answer()=0
callback results setter
AnswerT Answer
virtual ~WithAnswer()=default

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors