9 #ifndef FAIR_MQ_SDK_ASIOASYNCOP_H 10 #define FAIR_MQ_SDK_ASIOASYNCOP_H 12 #include <asio/associated_allocator.hpp> 13 #include <asio/associated_executor.hpp> 14 #include <asio/executor_work_guard.hpp> 15 #include <asio/system_executor.hpp> 18 #include <fairmq/sdk/Error.h> 19 #include <fairmq/sdk/Traits.h> 22 #include <system_error> 23 #include <type_traits> 26 #include <fairlogger/Logger.h> 35 template<
typename... SignatureArgTypes>
38 virtual auto Complete(std::error_code, SignatureArgTypes...) ->
void = 0;
39 virtual auto IsCompleted()
const ->
bool = 0;
46 template<
typename Executor1,
typename Allocator1,
typename Handler,
typename... SignatureArgTypes>
50 using Allocator2 =
typename asio::associated_allocator<Handler, Allocator1>::type;
53 using Executor2 =
typename asio::associated_executor<Handler, Executor1>::type;
58 , fWork2(
asio::get_associated_executor(handler, ex1))
59 , fHandler(
std::move(handler))
60 , fAlloc1(
std::move(alloc1))
63 auto GetAlloc2()
const ->
Allocator2 {
return asio::get_associated_allocator(fHandler, fAlloc1); }
64 auto GetEx2()
const ->
Executor2 {
return asio::get_associated_executor(fWork2); }
66 auto Complete(std::error_code ec, SignatureArgTypes... args) ->
void override 73 [=, handler = std::move(fHandler)]()
mutable {
76 }
catch (
const std::exception& e) {
77 FAIR_LOG(error) <<
"Uncaught exception in AsioAsyncOp completion handler: " << e.what();
79 FAIR_LOG(error) <<
"Unknown uncaught exception in AsioAsyncOp completion handler.";
88 auto IsCompleted()
const ->
bool override 90 return !fWork1.owns_work() && !fWork2.owns_work();
95 asio::executor_work_guard<Executor1> fWork1;
96 asio::executor_work_guard<Executor2> fWork2;
114 template<
typename Executor,
typename Allocator,
typename CompletionSignature>
128 template<
typename Executor,
130 typename SignatureReturnType,
131 typename SignatureFirstArgType,
132 typename... SignatureArgTypes>
135 SignatureReturnType(SignatureFirstArgType, SignatureArgTypes...)>
137 static_assert(std::is_void<SignatureReturnType>::value,
138 "return value of CompletionSignature must be void");
139 static_assert(std::is_same<SignatureFirstArgType, std::error_code>::value,
140 "first argument of CompletionSignature must be std::error_code");
141 using Duration = std::chrono::milliseconds;
145 using ImplPtr = std::unique_ptr<Impl, std::function<void(Impl*)>>;
155 template<
typename Handler>
160 using Op =
AsioAsyncOpImpl<Executor, Allocator, Handler, SignatureArgTypes...>;
165 typename std::allocator_traits<typename Op::Allocator2>::template rebind_alloc<Op>;
169 auto mem(std::allocator_traits<OpAllocator>::allocate(opAlloc, 1));
172 auto ptr(
new (mem) Op(std::move(ex1),
174 std::forward<Handler>(handler)));
177 fImpl = ImplPtr(ptr, [opAlloc](
Impl* p)
mutable {
178 std::allocator_traits<OpAllocator>::deallocate(opAlloc, static_cast<Op*>(p), 1);
183 template<
typename Handler>
189 template<
typename Handler>
194 auto IsCompleted() ->
bool {
return (fImpl ==
nullptr) || fImpl->IsCompleted(); }
196 auto Complete(std::error_code ec, SignatureArgTypes... args) ->
void 199 throw RuntimeError(
"Async operation already completed");
202 fImpl->Complete(ec, args...);
203 fImpl.reset(
nullptr);
206 auto Complete(SignatureArgTypes... args) ->
void 208 Complete(std::error_code(), args...);
211 auto Cancel(SignatureArgTypes... args) ->
void 213 Complete(MakeErrorCode(ErrorCode::OperationCanceled), args...);
216 auto Timeout(SignatureArgTypes... args) ->
void 218 Complete(MakeErrorCode(ErrorCode::OperationTimeout), args...);
Definition: AsioAsyncOp.h:47
Interface for Asio-compliant asynchronous operation, see https://www.boost.org/doc/libs/1_70_0/doc/ht...
Definition: AsioAsyncOp.h:115
Definition: AsioAsyncOp.h:36
AsioAsyncOpImpl(const Executor1 &ex1, Allocator1 alloc1, Handler &&handler)
Ctor.
Definition: AsioAsyncOp.h:56
typename asio::associated_executor< Handler, Executor1 >::type Executor2
See https://www.boost.org/doc/libs/1_70_0/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.associated_completion_handler_executor.
Definition: AsioAsyncOp.h:53
AsioAsyncOp(Executor ex1, Handler &&handler)
Ctor with handler #2.
Definition: AsioAsyncOp.h:184
AsioAsyncOp(Handler &&handler)
Ctor with handler #3.
Definition: AsioAsyncOp.h:190
AsioAsyncOp()
Default Ctor.
Definition: AsioAsyncOp.h:150
typename asio::associated_allocator< Handler, Allocator1 >::type Allocator2
See https://www.boost.org/doc/libs/1_70_0/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.allocation_of_intermediate_storage.
Definition: AsioAsyncOp.h:50
Tools for interfacing containers to the transport via polymorphic allocators.
Definition: DeviceRunner.h:23
AsioAsyncOp(Executor ex1, Allocator alloc1, Handler &&handler)
Ctor with handler.
Definition: AsioAsyncOp.h:156