2 Copyright Oliver Kowalke 2013.
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt
8 [section:channels Channels]
10 __boost_fiber__ provides a bounded and a unbounded channel suitable to
11 synchonize fibers via message passing.
13 typedef boost::fibers::unbounded_channel< int > channel_t;
15 void send( channel_t & channel) {
16 for ( int i = 0; i < 5; ++i) {
22 void recv( channel_t & channel) {
24 while ( boost::fibers::channel_op_status::success == channel.pop(i) ) {
25 std::cout << "received " << i << std::endl;
30 boost::fibers::fiber f1( std::bind( send, ref( channel) ) );
31 boost::fibers::fiber f2( std::bind( recv, ref( channel) ) );
36 [#class_channel_op_status]
37 [heading Enumeration `channel_op_status`]
39 channel operations return the state of the channel.
41 enum class channel_op_status {
51 [[Effects:] [Operation was successful.]]
56 [[Effects:] [channel is empty, operation failed.]]
61 [[Effects:] [channel is full, operation failed.]]
66 [[Effects:] [channel is closed, operation failed.]]
71 [[Effects:] [The operation did not become ready before specified timeout elapsed.]]
74 [template_heading unbounded_channel]
76 #include <boost/fiber/unbounded_channel.hpp>
81 template< typename T, typename __Allocator__ = __allocator__ >
82 class unbounded_channel {
86 explicit unbounded_channel( __Allocator__ const& alloc = Allocator() ) noexcept;
88 unbounded_channel( unbounded_channel const& other) = delete;
89 unbounded_channel & operator=( unbounded_channel const& other) = delete;
91 void close() noexcept;
93 channel_op_status push( value_type const& va);
94 channel_op_status push( value_type && va);
96 channel_op_status pop( value_type & va);
97 value_type value_pop();
98 channel_op_status try_pop( value_type & va);
99 template< typename Rep, typename Period >
100 channel_op_status pop_wait_for(
102 std::chrono::duration< Rep, Period > const& timeout_duration);
103 template< typename Clock, typename Duration >
104 channel_op_status pop_wait_until(
106 std::chrono::time_point< Clock, Duration > const& timeout_time);
111 [heading Constructor]
113 explicit unbounded_channel( __Allocator__ const& alloc = Allocator() ) noexcept;
116 [[Effects:] [Constructs an object of class `unbounded_channel`.
117 Internal nodes are allocated using `alloc` - C++11-allocators are supported.]]
118 [[Throws:] [Nothing.]]
119 [[See also:] [__Allocator__ concept, __allocator__]]
122 [template xchannel_close[cls]
123 [member_heading [cls]..close]
125 void close() noexcept;
128 [[Effects:] [Deactivates the channel. No values can be put after calling
129 `this->close()`. Fibers blocked in `this->pop()`, `this->pop_wait_for()`
130 or `this->pop_wait_until()` will return `closed`. Fibers blocked in
131 `this->value_pop()` will receive an exception.]]
132 [[Throws:] [Nothing.]]
133 [[Note:] [`close()` is like closing a pipe. It informs waiting consumers
134 that no more values will arrive.]]
137 [xchannel_close unbounded_channel]
139 [template xchannel_push_effects[enqueues] If channel is closed, returns
140 `closed`. [enqueues] the value in the channel, wakes up a fiber
141 blocked on `this->pop()`, `this->value_pop()`, `this->pop_wait_for()` or
142 `this->pop_wait_until()` and returns `success`.]
144 [member_heading unbounded_channel..push]
146 channel_op_status push( value_type const& va);
147 channel_op_status push( value_type && va);
150 [[Effects:] [[xchannel_push_effects Otherwise enqueues]]]
151 [[Throws:] [Exceptions thrown by memory allocation and copying or moving
155 [template xchannel_pop[cls unblocking]
156 [member_heading [cls]..pop]
158 channel_op_status pop( value_type & va);
161 [[Effects:] [Dequeues a value from the channel. If the channel is empty, the
162 fiber gets suspended until at least one new item is `push()`ed (return value
163 `success` and `va` contains dequeued value) or the channel gets `close()`d
164 (return value `closed`)[unblocking]]]
165 [[Throws:] [Nothing]]
168 [xchannel_pop unbounded_channel .]
170 [template xchannel_value_pop[cls unblocking]
171 [member_heading [cls]..value_pop]
173 value_type value_pop();
176 [[Effects:] [Dequeues a value from the channel. If the channel is empty, the
177 fiber gets suspended until at least one new item is `push()`ed or the channel
178 gets `close()`d (which throws an exception)[unblocking]]]
179 [[Throws:] [`fiber_error` if `*this` is closed]]
180 [[Error conditions:] [`std::errc::operation_not_permitted`]]
183 [xchannel_value_pop unbounded_channel .]
185 [template xchannel_try_pop[cls unblocking]
186 [member_heading [cls]..try_pop]
188 channel_op_status try_pop( value_type & va);
191 [[Effects:] [If channel is empty, returns `empty`. If channel is closed,
192 returns `closed`. Otherwise it returns `success` and `va` contains the
193 dequeued value[unblocking]]]
194 [[Throws:] [Exceptions thrown by copy- or move-operations.]]
197 [xchannel_try_pop unbounded_channel .]
199 [template xchannel_pop_wait_until_effects[endtime unblocking] If channel
200 is not empty, immediately dequeues a value from the channel. Otherwise
201 the fiber gets suspended until at least one new item is `push()`ed (return
202 value `success` and `va` contains dequeued value), or the channel gets
203 `close()`d (return value `closed`), or the system time reaches [endtime]
204 (return value `timeout`)[unblocking]]
206 [template xchannel_pop_wait_for[cls unblocking]
207 [member_heading [cls]..pop_wait_for]
209 template< typename Rep, typename Period >
210 channel_op_status pop_wait_for(
212 std::chrono::duration< Rep, Period > const& timeout_duration)
215 [[Effects:] [Accepts `std::chrono::duration` and internally computes a timeout
216 time as (system time + `timeout_duration`).
217 [xchannel_pop_wait_until_effects the computed timeout time..[unblocking]]]]
218 [[Throws:] [timeout-related exceptions.]]
221 [xchannel_pop_wait_for unbounded_channel .]
223 [template xchannel_pop_wait_until[cls unblocking]
224 [member_heading [cls]..pop_wait_until]
226 template< typename Clock, typename Duration >
227 channel_op_status pop_wait_until(
229 std::chrono::time_point< Clock, Duration > const& timeout_time)
232 [[Effects:] [Accepts a `std::chrono::time_point< Clock, Duration >`.
233 [xchannel_pop_wait_until_effects the passed `time_point`..[unblocking]]]]
234 [[Throws:] [timeout-related exceptions.]]
237 [xchannel_pop_wait_until unbounded_channel .]
240 [template_heading bounded_channel]
242 #include <boost/fiber/bounded_channel.hpp>
247 template< typename T, typename __Allocator__ = __allocator__ >
248 class bounded_channel {
250 typedef T value_type;
252 bounded_channel( std::size_t wm, __Allocator__ const& alloc = Allocator() );
253 bounded_channel( std::size_t hwm, std::size_t lwm, __Allocator__ const& alloc = Allocator() );
255 bounded_channel( bounded_channel const& other) = delete;
256 bounded_channel & operator=( bounded_channel const& other) = delete;
258 std::size_t upper_bound() const noexcept;
259 std::size_t lower_bound() const noexcept;
261 void close() noexcept;
263 channel_op_status push( value_type const& va);
264 channel_op_status push( value_type && va);
265 template< typename Rep, typename Period >
266 channel_op_status push_wait_for(
267 value_type const& va,
268 std::chrono::duration< Rep, Period > const& timeout_duration);
269 channel_op_status push_wait_for( value_type && va,
270 std::chrono::duration< Rep, Period > const& timeout_duration);
271 template< typename Clock, typename Duration >
272 channel_op_status push_wait_until(
273 value_type const& va,
274 std::chrono::time_point< Clock, Duration > const& timeout_time);
275 template< typename Clock, typename Duration >
276 channel_op_status push_wait_until(
278 std::chrono::time_point< Clock, Duration > const& timeout_time);
279 channel_op_status try_push( value_type const& va);
280 channel_op_status try_push( value_type && va);
282 channel_op_status pop( value_type & va);
283 value_type value_pop();
284 template< typename Rep, typename Period >
285 channel_op_status pop_wait_for(
287 std::chrono::duration< Rep, Period > const& timeout_duration);
288 template< typename Clock, typename Duration >
289 channel_op_status pop_wait_until(
291 std::chrono::time_point< Clock, Duration > const& timeout_time);
292 channel_op_status try_pop( value_type & va);
297 [heading Constructor]
299 bounded_channel( std::size_t wm, __Allocator__ const& alloc = Allocator() );
300 bounded_channel( std::size_t hwm, std::size_t lwm, __Allocator__ const& alloc = Allocator() );
303 [[Preconditions:] [`hwm > lwm`]]
304 [[Effects:] [Constructs an object of class `bounded_channel`. The constructor
305 with two arguments constructs an object of class `bounded_channel` with a
306 high-watermark of `hwm` and a low-watermark of `lwm` items. The constructor
307 with one `std::size_t` argument is effectively the same as `bounded_channel(wm, (wm-1), alloc)`.
308 Internal nodes are allocated using `alloc` - C++11-allocators are supported.]]
309 [[Throws:] [`fiber_error`]]
310 [[Error Conditions:] [
311 [*invalid_argument]: if `lwm >= hwm`.]]
312 [[Notes:] [Once the number of values in the channel reaches `hwm`, any call to
313 `push()`, `push_wait_for()` or `push_wait_until()` will block until the number
314 of values in the channel is at most `lwm`. That is, if `lwm < (hwm-1)`, the
315 channel can be in a state in which `push()`, `push_wait_for()` or `push_wait_until()`
316 calls will block (channel is full) even though the number of values
317 in the channel is less than `hwm`.]]
318 [[See also:] [__Allocator__ concept, __allocator__]]
321 [member_heading bounded_channel..upper_bound]
323 std::size_t upper_bound() const noexcept;
326 [[Returns:] [the high-watermark with which `*this` was constructed.]]
327 [[Throws:] [Nothing.]]
330 [member_heading bounded_channel..lower_bound]
332 std::size_t lower_bound() const noexcept;
335 [[Returns:] [the low-watermark with which `*this` was constructed.]]
336 [[Throws:] [Nothing.]]
339 [xchannel_close bounded_channel]
341 [template bounded_channel_push_effects[or] [xchannel_push_effects If channel
342 is not full, enqueues] Otherwise the calling fiber is suspended until
343 the number of values in the channel drops to `lwm` (return value
344 `success`)[or] the channel is `close()`d (return value `closed`)]
346 [member_heading bounded_channel..push]
348 channel_op_status push( value_type const& va);
349 channel_op_status push( value_type && va);
352 [[Effects:] [[bounded_channel_push_effects or].]]
353 [[Throws:] [exceptions thrown by memory
354 allocation and copying or moving `va`.]]
357 [member_heading bounded_channel..push_wait_for]
359 template< typename Rep, typename Period >
360 channel_op_status push_wait_for(
361 value_type const& va,
362 std::chrono::duration< Rep, Period > const& timeout_duration);
364 template< typename Rep, typename Period >
365 channel_op_status push_wait_for(
367 std::chrono::duration< Rep, Period > const& timeout_duration);
370 [[Effects:] [Accepts `std::chrono::duration` and internally computes a
371 time_point as (system time + `timeout_duration`).
372 [bounded_channel_push_effects ,], or the system time reaches the computed
373 time_point (return value `timeout`).]]
374 [[Throws:] [exceptions thrown by memory
375 allocation and copying or moving `va` or timeout-related exceptions.]]
378 [member_heading bounded_channel..push_wait_until]
380 template< typename Clock, typename Duration >
381 channel_op_status push_wait_until(
382 value_type const& va,
383 std::chrono::time_point< Clock, Duration > const& timeout_time);
385 template< typename Clock, typename Duration >
386 channel_op_status push_wait_until(
388 std::chrono::time_point< Clock, Duration > const& timeout_time);
391 [[Effects:] [Accepts an absolute `timeout_time` in any supported time_point
392 type. [bounded_channel_push_effects ,], or the system time reaches the passed
393 time_point (return value `timeout`).]]
394 [[Throws:] [exceptions thrown by memory
395 allocation and copying or moving `va` or timeout-related exceptions.]]
398 [member_heading bounded_channel..try_push]
400 channel_op_status try_push( value_type const& va);
401 channel_op_status try_push( value_type && va);
404 [[Effects:] [If channel is full, returns `full`.
405 [xchannel_push_effects Otherwise enqueues]]]
406 [[Throws:] [Exceptions thrown by memory
407 allocation and copying or moving `va`.]]
410 [template bounded_pop_unblocking[] Once the number of items remaining in the
411 channel drops to `lwm`, any fibers blocked on `push()`, `push_wait_for()`
412 or `push_wait_until()` may resume.]
414 [xchannel_pop bounded_channel... [bounded_pop_unblocking]]
415 [xchannel_value_pop bounded_channel... [bounded_pop_unblocking]]
416 [xchannel_try_pop bounded_channel... [bounded_pop_unblocking]]
417 [xchannel_pop_wait_for bounded_channel... [bounded_pop_unblocking]]
418 [xchannel_pop_wait_until bounded_channel... [bounded_pop_unblocking]]