2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-20 02:32:19 +00:00
Files
fiber/doc/queue.qbk
2016-10-13 20:17:01 +02:00

421 lines
14 KiB
Plaintext

[/
Copyright Oliver Kowalke 2013.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
]
[section:queues Queues]
__boost_fiber__ provides a bounded and a unbounded queue suitable to
synchonize fibers via message passing.
typedef boost::fibers::unbounded_queue< int > queue_t;
void send( queue_t & queue) {
for ( int i = 0; i < 5; ++i) {
queue.push( i);
}
queue.close();
}
void recv( queue_t & queue) {
int i;
while ( boost::fibers::queue_op_status::success == queue.pop(i) ) {
std::cout << "received " << i << std::endl;
}
}
queue_t queue;
boost::fibers::fiber f1( std::bind( send, ref( queue) ) );
boost::fibers::fiber f2( std::bind( recv, ref( queue) ) );
f1.join();
f2.join();
[#class_queue_op_status]
[heading Enumeration `queue_op_status`]
queue operations return the state of the queue.
enum class queue_op_status {
success,
empty,
full,
closed,
timeout
};
[heading `success`]
[variablelist
[[Effects:] [Operation was successful.]]
]
[heading `empty`]
[variablelist
[[Effects:] [queue is empty, operation failed.]]
]
[heading `full`]
[variablelist
[[Effects:] [queue is full, operation failed.]]
]
[heading `closed`]
[variablelist
[[Effects:] [queue is closed, operation failed.]]
]
[heading `timeout`]
[variablelist
[[Effects:] [The operation did not become ready before specified timeout elapsed.]]
]
[template_heading unbounded_queue]
#include <boost/fiber/unbounded_queue.hpp>
namespace boost {
namespace fibers {
template< typename T, typename __Allocator__ = __allocator__ >
class unbounded_queue {
public:
typedef T value_type;
explicit unbounded_queue( __Allocator__ const& alloc = Allocator() ) noexcept;
unbounded_queue( unbounded_queue const& other) = delete;
unbounded_queue & operator=( unbounded_queue const& other) = delete;
void close() noexcept;
queue_op_status push( value_type const& va);
queue_op_status push( value_type && va);
queue_op_status pop( value_type & va);
value_type value_pop();
queue_op_status try_pop( value_type & va);
template< typename Rep, typename Period >
queue_op_status pop_wait_for(
value_type & va,
std::chrono::duration< Rep, Period > const& timeout_duration);
template< typename Clock, typename Duration >
queue_op_status pop_wait_until(
value_type & va,
std::chrono::time_point< Clock, Duration > const& timeout_time);
};
}}
[heading Constructor]
explicit unbounded_queue( __Allocator__ const& alloc = Allocator() ) noexcept;
[variablelist
[[Effects:] [Constructs an object of class `unbounded_queue`.
Internal nodes are allocated using `alloc` - C++11-allocators are supported.]]
[[Throws:] [Nothing.]]
[[See also:] [__Allocator__ concept, __allocator__]]
]
[template xqueue_close[cls]
[member_heading [cls]..close]
void close() noexcept;
[variablelist
[[Effects:] [Deactivates the queue. No values can be put after calling
`this->close()`. Fibers blocked in `this->pop()`, `this->pop_wait_for()`
or `this->pop_wait_until()` will return `closed`. Fibers blocked in
`this->value_pop()` will receive an exception.]]
[[Throws:] [Nothing.]]
[[Note:] [`close()` is like closing a pipe. It informs waiting consumers
that no more values will arrive.]]
]
]
[xqueue_close unbounded_queue]
[template xqueue_push_effects[enqueues] If queue is closed, returns
`closed`. [enqueues] the value in the queue, wakes up a fiber
blocked on `this->pop()`, `this->value_pop()`, `this->pop_wait_for()` or
`this->pop_wait_until()` and returns `success`.]
[member_heading unbounded_queue..push]
queue_op_status push( value_type const& va);
queue_op_status push( value_type && va);
[variablelist
[[Effects:] [[xqueue_push_effects Otherwise enqueues]]]
[[Throws:] [Exceptions thrown by memory allocation and copying or moving
`va`.]]
]
[template xqueue_pop[cls unblocking]
[member_heading [cls]..pop]
queue_op_status pop( value_type & va);
[variablelist
[[Effects:] [Dequeues a value from the queue. If the queue is empty, the
fiber gets suspended until at least one new item is `push()`ed (return value
`success` and `va` contains dequeued value) or the queue gets `close()`d
(return value `closed`)[unblocking]]]
[[Throws:] [Nothing]]
]
]
[xqueue_pop unbounded_queue .]
[template xqueue_value_pop[cls unblocking]
[member_heading [cls]..value_pop]
value_type value_pop();
[variablelist
[[Effects:] [Dequeues a value from the queue. If the queue is empty, the
fiber gets suspended until at least one new item is `push()`ed or the queue
gets `close()`d (which throws an exception)[unblocking]]]
[[Throws:] [`fiber_error` if `*this` is closed]]
[[Error conditions:] [`std::errc::operation_not_permitted`]]
]
]
[xqueue_value_pop unbounded_queue .]
[template xqueue_try_pop[cls unblocking]
[member_heading [cls]..try_pop]
queue_op_status try_pop( value_type & va);
[variablelist
[[Effects:] [If queue is empty, returns `empty`. If queue is closed,
returns `closed`. Otherwise it returns `success` and `va` contains the
dequeued value[unblocking]]]
[[Throws:] [Exceptions thrown by copy- or move-operations.]]
]
]
[xqueue_try_pop unbounded_queue .]
[template xqueue_pop_wait_until_effects[endtime unblocking] If queue
is not empty, immediately dequeues a value from the queue. Otherwise
the fiber gets suspended until at least one new item is `push()`ed (return
value `success` and `va` contains dequeued value), or the queue gets
`close()`d (return value `closed`), or the system time reaches [endtime]
(return value `timeout`)[unblocking]]
[template xqueue_pop_wait_for[cls unblocking]
[member_heading [cls]..pop_wait_for]
template< typename Rep, typename Period >
queue_op_status pop_wait_for(
value_type & va,
std::chrono::duration< Rep, Period > const& timeout_duration)
[variablelist
[[Effects:] [Accepts `std::chrono::duration` and internally computes a timeout
time as (system time + `timeout_duration`).
[xqueue_pop_wait_until_effects the computed timeout time..[unblocking]]]]
[[Throws:] [timeout-related exceptions.]]
]
]
[xqueue_pop_wait_for unbounded_queue .]
[template xqueue_pop_wait_until[cls unblocking]
[member_heading [cls]..pop_wait_until]
template< typename Clock, typename Duration >
queue_op_status pop_wait_until(
value_type & va,
std::chrono::time_point< Clock, Duration > const& timeout_time)
[variablelist
[[Effects:] [Accepts a `std::chrono::time_point< Clock, Duration >`.
[xqueue_pop_wait_until_effects the passed `time_point`..[unblocking]]]]
[[Throws:] [timeout-related exceptions.]]
]
]
[xqueue_pop_wait_until unbounded_queue .]
[template_heading bounded_queue]
#include <boost/fiber/bounded_queue.hpp>
namespace boost {
namespace fibers {
template< typename T, typename __Allocator__ = __allocator__ >
class bounded_queue {
public:
typedef T value_type;
bounded_queue( std::size_t wm, __Allocator__ const& alloc = Allocator() );
bounded_queue( std::size_t hwm, std::size_t lwm, __Allocator__ const& alloc = Allocator() );
bounded_queue( bounded_queue const& other) = delete;
bounded_queue & operator=( bounded_queue const& other) = delete;
std::size_t upper_bound() const noexcept;
std::size_t lower_bound() const noexcept;
void close() noexcept;
queue_op_status push( value_type const& va);
queue_op_status push( value_type && va);
template< typename Rep, typename Period >
queue_op_status push_wait_for(
value_type const& va,
std::chrono::duration< Rep, Period > const& timeout_duration);
queue_op_status push_wait_for( value_type && va,
std::chrono::duration< Rep, Period > const& timeout_duration);
template< typename Clock, typename Duration >
queue_op_status push_wait_until(
value_type const& va,
std::chrono::time_point< Clock, Duration > const& timeout_time);
template< typename Clock, typename Duration >
queue_op_status push_wait_until(
value_type && va,
std::chrono::time_point< Clock, Duration > const& timeout_time);
queue_op_status try_push( value_type const& va);
queue_op_status try_push( value_type && va);
queue_op_status pop( value_type & va);
value_type value_pop();
template< typename Rep, typename Period >
queue_op_status pop_wait_for(
value_type & va,
std::chrono::duration< Rep, Period > const& timeout_duration);
template< typename Clock, typename Duration >
queue_op_status pop_wait_until(
value_type & va,
std::chrono::time_point< Clock, Duration > const& timeout_time);
queue_op_status try_pop( value_type & va);
};
}}
[heading Constructor]
bounded_queue( std::size_t wm, __Allocator__ const& alloc = Allocator() );
bounded_queue( std::size_t hwm, std::size_t lwm, __Allocator__ const& alloc = Allocator() );
[variablelist
[[Preconditions:] [`hwm > lwm`]]
[[Effects:] [Constructs an object of class `bounded_queue`. The constructor
with two arguments constructs an object of class `bounded_queue` with a
high-watermark of `hwm` and a low-watermark of `lwm` items. The constructor
with one `std::size_t` argument is effectively the same as `bounded_queue(wm, (wm-1), alloc)`.
Internal nodes are allocated using `alloc` - C++11-allocators are supported.]]
[[Throws:] [`fiber_error`]]
[[Error Conditions:] [
[*invalid_argument]: if `lwm >= hwm`.]]
[[Notes:] [Once the number of values in the queue reaches `hwm`, any call to
`push()`, `push_wait_for()` or `push_wait_until()` will block until the number
of values in the queue is at most `lwm`. That is, if `lwm < (hwm-1)`, the
queue can be in a state in which `push()`, `push_wait_for()` or `push_wait_until()`
calls will block (queue is full) even though the number of values
in the queue is less than `hwm`.]]
[[See also:] [__Allocator__ concept, __allocator__]]
]
[member_heading bounded_queue..upper_bound]
std::size_t upper_bound() const noexcept;
[variablelist
[[Returns:] [the high-watermark with which `*this` was constructed.]]
[[Throws:] [Nothing.]]
]
[member_heading bounded_queue..lower_bound]
std::size_t lower_bound() const noexcept;
[variablelist
[[Returns:] [the low-watermark with which `*this` was constructed.]]
[[Throws:] [Nothing.]]
]
[xqueue_close bounded_queue]
[template bounded_queue_push_effects[or] [xqueue_push_effects If queue
is not full, enqueues] Otherwise the calling fiber is suspended until
the number of values in the queue drops to `lwm` (return value
`success`)[or] the queue is `close()`d (return value `closed`)]
[member_heading bounded_queue..push]
queue_op_status push( value_type const& va);
queue_op_status push( value_type && va);
[variablelist
[[Effects:] [[bounded_queue_push_effects or].]]
[[Throws:] [exceptions thrown by memory
allocation and copying or moving `va`.]]
]
[member_heading bounded_queue..push_wait_for]
template< typename Rep, typename Period >
queue_op_status push_wait_for(
value_type const& va,
std::chrono::duration< Rep, Period > const& timeout_duration);
template< typename Rep, typename Period >
queue_op_status push_wait_for(
value_type && va,
std::chrono::duration< Rep, Period > const& timeout_duration);
[variablelist
[[Effects:] [Accepts `std::chrono::duration` and internally computes a
time_point as (system time + `timeout_duration`).
[bounded_queue_push_effects ,], or the system time reaches the computed
time_point (return value `timeout`).]]
[[Throws:] [exceptions thrown by memory
allocation and copying or moving `va` or timeout-related exceptions.]]
]
[member_heading bounded_queue..push_wait_until]
template< typename Clock, typename Duration >
queue_op_status push_wait_until(
value_type const& va,
std::chrono::time_point< Clock, Duration > const& timeout_time);
template< typename Clock, typename Duration >
queue_op_status push_wait_until(
value_type && va,
std::chrono::time_point< Clock, Duration > const& timeout_time);
[variablelist
[[Effects:] [Accepts an absolute `timeout_time` in any supported time_point
type. [bounded_queue_push_effects ,], or the system time reaches the passed
time_point (return value `timeout`).]]
[[Throws:] [exceptions thrown by memory
allocation and copying or moving `va` or timeout-related exceptions.]]
]
[member_heading bounded_queue..try_push]
queue_op_status try_push( value_type const& va);
queue_op_status try_push( value_type && va);
[variablelist
[[Effects:] [If queue is full, returns `full`.
[xqueue_push_effects Otherwise enqueues]]]
[[Throws:] [Exceptions thrown by memory
allocation and copying or moving `va`.]]
]
[template bounded_pop_unblocking[] Once the number of items remaining in the
queue drops to `lwm`, any fibers blocked on `push()`, `push_wait_for()`
or `push_wait_until()` may resume.]
[xqueue_pop bounded_queue... [bounded_pop_unblocking]]
[xqueue_value_pop bounded_queue... [bounded_pop_unblocking]]
[xqueue_try_pop bounded_queue... [bounded_pop_unblocking]]
[xqueue_pop_wait_for bounded_queue... [bounded_pop_unblocking]]
[xqueue_pop_wait_until bounded_queue... [bounded_pop_unblocking]]
[endsect]