Qpid Proton C++ API 0.40.0
 
Loading...
Searching...
No Matches
work_queue.hpp
Go to the documentation of this file.
1#ifndef PROTON_WORK_QUEUE_HPP
2#define PROTON_WORK_QUEUE_HPP
3
4/*
5 *
6 * Licensed to the Apache Software Foundation (ASF) under one
7 * or more contributor license agreements. See the NOTICE file
8 * distributed with this work for additional information
9 * regarding copyright ownership. The ASF licenses this file
10 * to you under the Apache License, Version 2.0 (the
11 * "License"); you may not use this file except in compliance
12 * with the License. You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an
18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19 * KIND, either express or implied. See the License for the
20 * specific language governing permissions and limitations
21 * under the License.
22 *
23 */
24
25#include "./duration.hpp"
26#include "./fwd.hpp"
27#include "./function.hpp"
28#include "./internal/export.hpp"
29
30#include <functional>
31#include <memory>
32#include <type_traits>
33#include <utility>
34
35struct pn_connection_t;
36struct pn_session_t;
37struct pn_link_t;
38
41
42namespace proton {
43
45
46namespace internal { namespace v03 {
47
48struct invocable {
49 invocable() = default;
50 virtual ~invocable() = default;
51
52 virtual invocable& clone() const = 0;
53 virtual void operator() () = 0;
54};
55
56template <class T>
57struct invocable_cloner : invocable {
58 virtual ~invocable_cloner() = default;
59 virtual invocable& clone() const {
60 return *new T(static_cast<T const&>(*this));
61 }
62};
63
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_);
70 return *this;
71 }
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_; }
75
76 invocable_wrapper(const invocable& i): wrapped_(&i.clone()) {}
77 void operator()() { (*wrapped_)(); }
78
79 invocable* wrapped_;
80};
81
86class work {
87 public:
89 work() = default;
90
91 work(const invocable& i): item_(i) {}
92
94 void operator()() { item_(); }
95
96 ~work() = default;
97
98 private:
99 invocable_wrapper item_;
100};
101
102// Utilities to make work from functions/member functions (C++03 version)
103// Lots of repetition to handle functions/member functions with up to 3 arguments
104
105template <class R>
106struct work0 : public invocable_cloner<work0<R> > {
107 R (* fn_)();
108
109 work0(R (* f)()) :
110 fn_(f) {}
111
112 void operator()() {
113 (*fn_)();
114 }
115};
116
117template <class R, class A>
118struct work1 : public invocable_cloner<work1<R,A> > {
119 R (* fn_)(A);
120 A a_;
121
122 work1(R (* t)(A), A a) :
123 fn_(t), a_(a) {}
124
125 void operator()() {
126 (*fn_)(a_);
127 }
128};
129
130template <class R, class A, class B>
131struct work2 : public invocable_cloner<work2<R,A,B> > {
132 R (* fn_)(A, B);
133 A a_;
134 B b_;
135
136 work2(R (* t)(A, B), A a, B b) :
137 fn_(t), a_(a), b_(b) {}
138
139 void operator()() {
140 (*fn_)(a_, b_);
141 }
142};
143
144template <class R, class A, class B, class C>
145struct work3 : public invocable_cloner<work3<R,A,B,C> > {
146 R (* fn_)(A, B, C);
147 A a_;
148 B b_;
149 C c_;
150
151 work3(R (* t)(A, B, C), A a, B b, C c) :
152 fn_(t), a_(a), b_(b), c_(c) {}
153
154 void operator()() {
155 (*fn_)(a_, b_, c_);
156 }
157};
158
159template <class R, class T>
160struct work_pmf0 : public invocable_cloner<work_pmf0<R,T> > {
161 T& holder_;
162 R (T::* fn_)();
163
164 work_pmf0(R (T::* a)(), T& h) :
165 holder_(h), fn_(a) {}
166
167 void operator()() {
168 (holder_.*fn_)();
169 }
170};
171
172template <class R, class T, class A>
173struct work_pmf1 : public invocable_cloner<work_pmf1<R,T,A> > {
174 T& holder_;
175 R (T::* fn_)(A);
176 A a_;
177
178 work_pmf1(R (T::* t)(A), T& h, A a) :
179 holder_(h), fn_(t), a_(a) {}
180
181 void operator()() {
182 (holder_.*fn_)(a_);
183 }
184};
185
186template <class R, class T, class A, class B>
187struct work_pmf2 : public invocable_cloner<work_pmf2<R,T,A,B> > {
188 T& holder_;
189 R (T::* fn_)(A, B);
190 A a_;
191 B b_;
192
193 work_pmf2(R (T::* t)(A, B), T& h, A a, B b) :
194 holder_(h), fn_(t), a_(a), b_(b) {}
195
196 void operator()() {
197 (holder_.*fn_)(a_, b_);
198 }
199};
200
201template <class R, class T, class A, class B, class C>
202struct work_pmf3 : public invocable_cloner<work_pmf3<R,T,A,B,C> > {
203 T& holder_;
204 R (T::* fn_)(A, B, C);
205 A a_;
206 B b_;
207 C c_;
208
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) {}
211
212 void operator()() {
213 (holder_.*fn_)(a_, b_, c_);
214 }
215};
216
219template <class R, class T>
220work make_work(R (T::*f)(), T* t) {
221 return work_pmf0<R, T>(f, *t);
222}
223
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);
227}
228
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);
232}
233
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);
237}
238
239template <class R>
240work make_work(R (*f)()) {
241 return work0<R>(f);
242}
243
244template <class R, class A>
245work make_work(R (*f)(A), A a) {
246 return work1<R, A>(f, a);
247}
248
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);
252}
253
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);
257}
258
259} } // internal::v03
260
261
262namespace internal { namespace v11 {
263
264class work {
265 public:
267 work() = default;
268
274 template <class T,
275 // Make sure we don't match the copy or move constructors
276 class = typename std::enable_if<!std::is_same<typename std::decay<T>::type,work>::value>::type
277 >
278 work(T&& f): item_(std::forward<T>(f)) {}
279
283 void operator()() const { item_(); }
284
285 ~work() = default;
286
287 private:
288 std::function<void()> item_;
289};
290
298template <class... Rest>
299work make_work(Rest&&... r) {
300 return std::bind(std::forward<Rest>(r)...);
301}
302
303} } // internal::v11
304
305using internal::v11::work;
306using internal::v11::make_work;
307
308
310
327class PN_CPP_CLASS_EXTERN work_queue {
329 class impl;
330 work_queue& operator=(impl* i);
332
333 public:
335 PN_CPP_EXTERN work_queue();
336
338 PN_CPP_EXTERN work_queue(container&);
339
340 PN_CPP_EXTERN ~work_queue();
341
350 PN_CPP_EXTERN bool add(work fn);
351
353 PN_CPP_EXTERN PN_CPP_DEPRECATED("Use 'work_queue::add(work)'") bool add(void_function0& fn);
354
363 PN_CPP_EXTERN void schedule(duration, work fn);
364
366 PN_CPP_EXTERN PN_CPP_DEPRECATED("Use 'work_queue::schedule(duration, work)'") void schedule(duration, void_function0& fn);
367
368 private:
371 PN_CPP_EXTERN bool add(internal::v03::work fn);
372 PN_CPP_EXTERN void schedule(duration, internal::v03::work fn);
373
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*);
377
378 std::unique_ptr<impl> impl_;
379
381 friend class container;
382 friend class io::connection_driver;
384};
385
386} // proton
387
388#endif // PROTON_WORK_QUEUE_HPP
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.
Forward declarations.
The main Proton namespace.
Definition annotation_key.hpp:33