1#ifndef PROTON_WORK_QUEUE_HPP
2#define PROTON_WORK_QUEUE_HPP
28#include "./internal/export.hpp"
35struct pn_connection_t;
46namespace internal {
namespace v03 {
49 invocable() =
default;
50 virtual ~invocable() =
default;
52 virtual invocable& clone()
const = 0;
53 virtual void operator() () = 0;
57struct invocable_cloner : invocable {
58 virtual ~invocable_cloner() =
default;
59 virtual invocable& clone()
const {
60 return *
new T(
static_cast<T const&
>(*
this));
64struct invocable_wrapper {
65 invocable_wrapper(): wrapped_(0) {}
66 invocable_wrapper(
const invocable_wrapper& w): wrapped_(&w.wrapped_->clone()) {}
67 invocable_wrapper& operator=(
const invocable_wrapper& that) {
68 invocable_wrapper newthis(that);
69 std::swap(wrapped_, newthis.wrapped_);
72 invocable_wrapper(invocable_wrapper&& w): wrapped_(w.wrapped_) {}
73 invocable_wrapper& operator=(invocable_wrapper&& that) {
delete wrapped_; wrapped_ = that.wrapped_;
return *
this; }
74 ~invocable_wrapper() {
delete wrapped_; }
76 invocable_wrapper(
const invocable& i): wrapped_(&i.clone()) {}
77 void operator()() { (*wrapped_)(); }
91 work(
const invocable& i): item_(i) {}
94 void operator()() { item_(); }
99 invocable_wrapper item_;
106struct work0 :
public invocable_cloner<work0<R> > {
117template <
class R,
class A>
118struct work1 :
public invocable_cloner<work1<R,A> > {
122 work1(R (* t)(A), A a) :
130template <
class R,
class A,
class B>
131struct work2 :
public invocable_cloner<work2<R,A,B> > {
136 work2(R (* t)(A, B), A a, B b) :
137 fn_(t), a_(a), b_(b) {}
144template <
class R,
class A,
class B,
class C>
145struct work3 :
public invocable_cloner<work3<R,A,B,C> > {
151 work3(R (* t)(A, B, C), A a, B b, C c) :
152 fn_(t), a_(a), b_(b), c_(c) {}
159template <
class R,
class T>
160struct work_pmf0 :
public invocable_cloner<work_pmf0<R,T> > {
164 work_pmf0(R (T::* a)(), T& h) :
165 holder_(h), fn_(a) {}
172template <
class R,
class T,
class A>
173struct work_pmf1 :
public invocable_cloner<work_pmf1<R,T,A> > {
178 work_pmf1(R (T::* t)(A), T& h, A a) :
179 holder_(h), fn_(t), a_(a) {}
186template <
class R,
class T,
class A,
class B>
187struct work_pmf2 :
public invocable_cloner<work_pmf2<R,T,A,B> > {
193 work_pmf2(R (T::* t)(A, B), T& h, A a, B b) :
194 holder_(h), fn_(t), a_(a), b_(b) {}
197 (holder_.*fn_)(a_, b_);
201template <
class R,
class T,
class A,
class B,
class C>
202struct work_pmf3 :
public invocable_cloner<work_pmf3<R,T,A,B,C> > {
204 R (T::* fn_)(A, B, C);
209 work_pmf3(R (T::* t)(A, B, C), T& h, A a, B b, C c) :
210 holder_(h), fn_(t), a_(a), b_(b), c_(c) {}
213 (holder_.*fn_)(a_, b_, c_);
219template <
class R,
class T>
220work make_work(R (T::*f)(), T* t) {
221 return work_pmf0<R, T>(f, *t);
224template <
class R,
class T,
class A>
225work make_work(R (T::*f)(A), T* t, A a) {
226 return work_pmf1<R, T, A>(f, *t, a);
229template <
class R,
class T,
class A,
class B>
230work make_work(R (T::*f)(A, B), T* t, A a, B b) {
231 return work_pmf2<R, T, A, B>(f, *t, a, b);
234template <
class R,
class T,
class A,
class B,
class C>
235work make_work(R (T::*f)(A, B, C), T* t, A a, B b, C c) {
236 return work_pmf3<R, T, A, B, C>(f, *t, a, b, c);
240work make_work(R (*f)()) {
244template <
class R,
class A>
245work make_work(R (*f)(A), A a) {
246 return work1<R, A>(f, a);
249template <
class R,
class A,
class B>
250work make_work(R (*f)(A, B), A a, B b) {
251 return work2<R, A, B>(f, a, b);
254template <
class R,
class A,
class B,
class C>
255work make_work(R (*f)(A, B, C), A a, B b, C c) {
256 return work3<R, A, B, C>(f, a, b, c);
262namespace internal {
namespace v11 {
276 class =
typename std::enable_if<!std::is_same<typename std::decay<T>::type,work>::value>::type
278 work(T&& f): item_(std::forward<T>(f)) {}
283 void operator()()
const { item_(); }
288 std::function<void()> item_;
298template <
class... Rest>
299work make_work(Rest&&... r) {
300 return std::bind(std::forward<Rest>(r)...);
305using internal::v11::work;
306using internal::v11::make_work;
350 PN_CPP_EXTERN
bool add(work fn);
353 PN_CPP_EXTERN PN_CPP_DEPRECATED(
"Use 'work_queue::add(work)'") bool add(void_function0& fn);
371 PN_CPP_EXTERN
bool add(internal::v03::work fn);
372 PN_CPP_EXTERN
void schedule(
duration, internal::v03::work fn);
374 PN_CPP_EXTERN static
work_queue& get(pn_connection_t*);
375 PN_CPP_EXTERN static
work_queue& get(pn_session_t*);
376 PN_CPP_EXTERN static
work_queue& get(pn_link_t*);
378 std::unique_ptr<impl> impl_;
382 friend class io::connection_driver;
A top-level container of connections, sessions, and links.
Definition container.hpp:50
A span of time in milliseconds.
Definition duration.hpp:39
Unsettled API - A context for thread-safe execution of work.
Definition work_queue.hpp:327
work_queue()
Unsettled API - Create a work queue.
bool add(work fn)
Unsettled API - Add work fn to the work queue.
work_queue(container &)
Unsettled API - Create a work queue backed by a container.
A span of time in milliseconds.
Deprecated - Use the API in work_queue.hpp.
The main Proton namespace.
Definition annotation_key.hpp:33