Tamer
C++ language extensions for event-driven programming
Loading...
Searching...
No Matches
xadapter.hh
1#ifndef TAMER_XADAPTER_HH
2#define TAMER_XADAPTER_HH 1
3/* Copyright (c) 2007-2015, Eddie Kohler
4 * Copyright (c) 2007, Regents of the University of California
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, subject to the conditions
9 * listed in the Tamer LICENSE file. These conditions include: you must
10 * preserve this copyright notice, and you cannot mention the copyright
11 * holders in advertising related to the Software without their permission.
12 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
13 * notice is a summary of the Tamer LICENSE file; the license in that file is
14 * legally binding.
15 */
16#include <tamer/event.hh>
17#include <tamer/driver.hh>
18#include <cstring>
19#include <cerrno>
20#include <iterator>
21namespace tamer {
22namespace tamerpriv {
23
24extern char placeholder_buffer[64];
25
26class with_helper_rendezvous : public functional_rendezvous,
27 public zero_argument_rendezvous_tag<with_helper_rendezvous> {
28 public:
29 with_helper_rendezvous(simple_event *e, int *s0, int v0)
30 : functional_rendezvous(hook), e_(e), s0_(s0), v0_(v0) {
31 }
32 private:
33 simple_event *e_; // An e_->at_trigger() holds a reference
34 int *s0_; // to this rendezvous, so this rendezvous
35 int v0_; // doesn't hold a reference to e_.
36 static void hook(functional_rendezvous *fr, simple_event *, bool) TAMER_NOEXCEPT;
37};
38
39template <typename... TS>
40inline event<> with_helper(event<TS...> e, int *result, int value) {
41 with_helper_rendezvous *r = new with_helper_rendezvous(e.__get_simple(), result, value);
42 event<> with = tamer::make_event(*r);
43 e.at_trigger(with);
44 return with;
45}
46
47
48template <size_t I, typename VI, typename... TS>
49class bind_rendezvous : public functional_rendezvous,
50 public zero_argument_rendezvous_tag<bind_rendezvous<I, VI, TS...> > {
51 public:
52 bind_rendezvous(event<TS...>&& e, VI vi)
53 : functional_rendezvous(hook), e_(std::move(e)), vi_(std::move(vi)) {
54 }
55 event<> make_bound() {
56 event<> bound = TAMER_MAKE_FN_ANNOTATED_EVENT(*this);
57 e_.at_trigger(bound);
58 return bound;
59 }
60 private:
61 event<TS...> e_;
62 VI vi_;
63 static void hook(functional_rendezvous*, simple_event*, bool) TAMER_NOEXCEPT;
64};
65
66template <size_t I, typename VI, typename... TS>
67void bind_rendezvous<I, VI, TS...>::hook(functional_rendezvous* fr, simple_event*, bool) TAMER_NOEXCEPT {
68 bind_rendezvous<I, VI, TS...>* self = static_cast<bind_rendezvous<I, VI, TS...>*>(fr);
69 self->e_.template set_result<I>(self->vi_);
70 if (simple_event* se = self->e_.__release_simple()) {
71 se->simple_trigger(true);
72 }
73 delete self;
74}
75
76
77template <typename T, typename U> struct tuple_cons;
78template <typename T, typename... TS> struct tuple_cons<T, std::tuple<TS...> > {
79 typedef std::tuple<T, TS...> type;
80};
81
82template <typename... TS> struct ignore_analysis;
83template <> struct ignore_analysis<> {
84 typedef std::tuple<> type;
85 static const bool use_placeholder = true;
86 static const bool empty = true;
87};
88template <typename... TS> struct ignore_analysis<void, TS...> {
89 typedef typename ignore_analysis<TS...>::type type;
90 static const bool use_placeholder = ignore_analysis<TS...>::use_placeholder;
91 static const bool empty = ignore_analysis<TS...>::empty;
92};
93template <typename T, typename... TS> struct ignore_analysis<T, TS...> {
94 typedef typename tuple_cons<T, typename ignore_analysis<TS...>::type>::type type;
95 static const bool use_placeholder = ignore_analysis<TS...>::use_placeholder && std::is_trivial<T>::value && sizeof(type) <= sizeof(placeholder_buffer);
96 static const bool empty = false;
97};
98
99template <bool USE_PLACEHOLDER, typename... TS> struct ignore_binder;
100
101template <typename... TS> struct ignore_binder<false, TS...> {
102 typedef typename ignore_analysis<TS...>::type results_tuple_type;
103 static event<TS...> make(event<> e) {
104 results_tuple_type* vs = new results_tuple_type;
105 simple_event::at_trigger(e.__get_simple(), deleter, vs);
106 return event<TS...>(std::move(e), *vs);
107 }
108 static void deleter(void* x) {
109 delete static_cast<results_tuple_type*>(x);
110 }
111};
112
113template <typename... TS> struct ignore_binder<true, TS...> {
114 typedef typename ignore_analysis<TS...>::type results_tuple_type;
115 static event<TS...> make(event<> e) {
116 return event<TS...>(std::move(e), *new(placeholder_buffer) results_tuple_type);
117 }
118};
119
120template <typename... TS> struct rebinder {
121 static event<TS...> make(event<> e) {
122 return ignore_binder<ignore_analysis<TS...>::use_placeholder, TS...>::make(e);
123 }
124};
125
126
127template <typename T> struct decay { public: typedef T type; };
128template <typename T0, typename T1> struct decay<T0(T1)> { public: typedef T0 (*type)(T1); };
129
130template <typename S0, typename T0, typename F>
131class map_rendezvous : public functional_rendezvous,
132 public zero_argument_rendezvous_tag<map_rendezvous<S0, T0, F> > {
133 public:
134 map_rendezvous(const F& f, const event<T0>& e)
135 : functional_rendezvous(hook), f_(f), e_(e) {
136 }
137 S0& result0() {
138 return s0_;
139 }
140 private:
141 S0 s0_;
142 typename decay<F>::type f_;
143 event<T0> e_;
144 static void hook(functional_rendezvous *, simple_event *, bool) TAMER_NOEXCEPT;
145};
146
147template <typename S0, typename T0, typename F>
148void map_rendezvous<S0, T0, F>::hook(functional_rendezvous *fr,
149 simple_event *, bool values) TAMER_NOEXCEPT {
150 map_rendezvous *self = static_cast<map_rendezvous *>(fr);
151 if (values) {
152 self->e_.trigger(self->f_(self->s0_));
153 } else if (self->e_) {
154 self->e_.unblocker().trigger();
155 }
156 delete self;
157}
158
159
160template <typename F, typename A1=void, typename A2=void>
161class function_rendezvous;
162
163template <typename F, typename A1, typename A2>
164class function_rendezvous : public functional_rendezvous,
165 public zero_argument_rendezvous_tag<function_rendezvous<F, A1, A2> > {
166 public:
167 function_rendezvous(F f, A1 arg1, A2 arg2)
168 : functional_rendezvous(hook), f_(std::move(f)),
169 arg1_(std::move(arg1)), arg2_(std::move(arg2)) {
170 }
171 private:
172 F f_;
173 A1 arg1_;
174 A2 arg2_;
175 static void hook(functional_rendezvous*, simple_event*, bool) TAMER_NOEXCEPT;
176};
177
178template <typename F, typename A1, typename A2>
179void function_rendezvous<F, A1, A2>::hook(functional_rendezvous* fr,
180 simple_event*,
181 bool) TAMER_NOEXCEPT {
182 function_rendezvous<F, A1, A2>* self = static_cast<function_rendezvous<F, A1, A2>*>(fr);
183 // in case f_() refers to an event on this rendezvous:
184 self->remove_waiting();
185 self->f_(std::move(self->arg1_), std::move(self->arg2_));
186 delete self;
187}
188
189
190template <typename F, typename A>
191class function_rendezvous<F, A> : public functional_rendezvous,
192 public zero_argument_rendezvous_tag<function_rendezvous<F, A> > {
193 public:
194 function_rendezvous(F f, A arg)
195 : functional_rendezvous(hook), f_(std::move(f)),
196 arg_(std::move(arg)) {
197 }
198 private:
199 F f_;
200 A arg_;
201 static void hook(functional_rendezvous*, simple_event*, bool) TAMER_NOEXCEPT;
202};
203
204template <typename F, typename A>
205void function_rendezvous<F, A, void>::hook(functional_rendezvous* fr,
206 simple_event*,
207 bool) TAMER_NOEXCEPT {
208 function_rendezvous<F, A, void>* self = static_cast<function_rendezvous<F, A, void>*>(fr);
209 // in case f_() refers to an event on this rendezvous:
210 self->remove_waiting();
211 self->f_(std::move(self->arg_));
212 delete self;
213}
214
215
216template <typename F>
217class function_rendezvous<F> : public functional_rendezvous,
218 public zero_argument_rendezvous_tag<function_rendezvous<F> > {
219 public:
220 function_rendezvous(F f)
221 : functional_rendezvous(hook), f_(std::move(f)) {
222 }
223 private:
224 F f_;
225 static void hook(functional_rendezvous*, simple_event*, bool) TAMER_NOEXCEPT;
226};
227
228template <typename F>
229void function_rendezvous<F, void, void>::hook(functional_rendezvous* fr,
230 simple_event*,
231 bool) TAMER_NOEXCEPT {
232 function_rendezvous<F>* self = static_cast<function_rendezvous<F>*>(fr);
233 // in case f_() refers to an event on this rendezvous:
234 self->remove_waiting();
235 self->f_();
236 delete self;
237}
238
239
240template <typename C>
241class push_back_rendezvous : public functional_rendezvous,
242 public zero_argument_rendezvous_tag<push_back_rendezvous<C> > {
243 public:
244 typedef typename C::value_type value_type;
245 push_back_rendezvous(C& c)
246 : functional_rendezvous(hook), c_(c) {
247 }
248 value_type& slot() {
249 return slot_;
250 }
251 private:
252 C& c_;
253 value_type slot_;
254 static void hook(functional_rendezvous*, simple_event*, bool) TAMER_NOEXCEPT;
255};
256
257template <typename C>
258void push_back_rendezvous<C>::hook(functional_rendezvous* fr,
259 simple_event*,
260 bool values) TAMER_NOEXCEPT {
261 push_back_rendezvous<C>* self = static_cast<push_back_rendezvous<C>*>(fr);
262 self->remove_waiting();
263 if (values) {
264 self->c_.push_back(std::move(self->slot_));
265 }
266 delete self;
267}
268
269
270template <typename It>
271class output_rendezvous : public functional_rendezvous,
272 public zero_argument_rendezvous_tag<output_rendezvous<It> > {
273 public:
274 typedef typename std::iterator_traits<It>::value_type value_type;
275 output_rendezvous(It& it)
276 : functional_rendezvous(hook), it_(it) {
277 }
278 value_type& slot() {
279 return slot_;
280 }
281 private:
282 It& it_;
283 value_type slot_;
284 static void hook(functional_rendezvous*, simple_event*, bool) TAMER_NOEXCEPT;
285};
286
287template <typename It>
288void output_rendezvous<It>::hook(functional_rendezvous* fr,
289 simple_event*,
290 bool values) TAMER_NOEXCEPT {
291 output_rendezvous<It>* self = static_cast<output_rendezvous<It>*>(fr);
292 self->remove_waiting();
293 if (values) {
294 *self->it_ = std::move(self->slot_);
295 ++self->it_;
296 }
297 delete self;
298}
299
300} // namespace tamerpriv
301} // namespace tamer
302#endif /* TAMER_XADAPTER_HH */
Functions for registering primitive events and managing the event loop.
The event template classes and helper functions.
event< T0, T1, T2, T3 > make_event(one_argument_rendezvous_tag< R > &r, const I &eid, T0 &x0, T1 &x1, T2 &x2, T3 &x3)
Construct a four-result event on rendezvous r with ID eid.
Definition event.hh:1115
Namespace containing public Tamer classes and functions for the Tamer core.
Definition adapter.hh:17