mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-09 23:12:57 +00:00
309 lines
8.7 KiB
Plaintext
309 lines
8.7 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)
|
|
{
|
|
while ( ! queue.is_closed() )
|
|
{ std::cout << "received " << queue.value_pop() << std::endl; }
|
|
}
|
|
|
|
queue_t queue;
|
|
boost::fibers::fiber f1( boost::bind( send, ref( queue) ) );
|
|
boost::fibers::fiber f2( boost::bind( recv, ref( queue) ) );
|
|
|
|
f1.join();
|
|
f2.join();
|
|
|
|
[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 successfull.]]
|
|
]
|
|
|
|
[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 timout has passed.]]
|
|
]
|
|
|
|
[heading Template `unbounded_queue<>`]
|
|
|
|
#include <boost/fiber/unbounded_queue.hpp>
|
|
|
|
template< typename T >
|
|
class unbounded_queue
|
|
{
|
|
public:
|
|
typedef T value_type;
|
|
|
|
unbounded_queue( unbounded_queue const& other) = delete;
|
|
unbounded_queue & operator=( unbounded_queue const& other) = delete;
|
|
|
|
bool is_closed() const;
|
|
void close();
|
|
|
|
bool is_empty();
|
|
|
|
void push( value_type const& va);
|
|
void push( value_types &&) va);
|
|
|
|
value_type value_pop();
|
|
template< typename Rep, typename Period >
|
|
queue_op_status wait_pop( value_type & va,
|
|
chrono::duration< Rep, Period > const& timeout_duration)
|
|
queue_op_status wait_pop( value_type & va,
|
|
clock_type::time_point const& timeout_time)
|
|
queue_op_status try_pop( value_type & va);
|
|
};
|
|
|
|
[heading Member function `is_closed()`]
|
|
|
|
bool is_closed() const;
|
|
|
|
[variablelist
|
|
[[Effects:] [Return `true` if queue was closed.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [The queue is not closed by default.]]
|
|
]
|
|
|
|
[heading Member function `closed()`]
|
|
|
|
void closed();
|
|
|
|
[variablelist
|
|
[[Effects:] [Deactivates the queue. No values can be put after calling
|
|
`this->close`. Fibers blocked in `this->value_pop()` will return.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [`close()` is like closing a pipe. It informs waiting receivers
|
|
that no more values will arrive.]]
|
|
]
|
|
|
|
[heading Member function `is_empty()`]
|
|
|
|
bool is_empty();
|
|
|
|
[variablelist
|
|
[[Effects:] [Returns `true` if the queue currently contains no data.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [This condition is transient. An `is_empty()` queue can become
|
|
non-empty.]]
|
|
]
|
|
|
|
[heading Member function `push()`]
|
|
|
|
void push( value_type const& va);
|
|
void push( value_type && va);
|
|
|
|
[variablelist
|
|
[[Effects:] [Enqueues the value in the queue and wakes up a fiber waiting
|
|
for new data available from the queue.]]
|
|
[[Throws:] [Nothing.]]
|
|
]
|
|
|
|
[heading Member function `take()`]
|
|
|
|
bool take( boost::optional< T > & va);
|
|
|
|
[variablelist
|
|
[[Effects:] [Dequeues a value from the queue. If no data is available from the
|
|
queue the fiber gets suspended until at least one new item is enqueued (return
|
|
value `true` and va contains dequeued value) or the queue gets deactivated and
|
|
the function returns `false`.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [interruption point]]
|
|
]
|
|
|
|
[heading Member function `try_take()`]
|
|
|
|
bool try_take( boost::optional< T > & va);
|
|
|
|
[variablelist
|
|
[[Effects:] [Dequeues a value from the queue. If no data can be retrieved from
|
|
the queue at this moment, the function returns `false`. Otherwise it returns
|
|
`true` and `va` contains the dequeued value.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [A return value of `false` does not distinguish between `empty()` and
|
|
`(! active())`.]]
|
|
]
|
|
|
|
|
|
[heading Template `bounded_queue<>`]
|
|
|
|
#include <boost/fiber/bounded_queue.hpp>
|
|
|
|
template< typename T >
|
|
class bounded_queue
|
|
{
|
|
public:
|
|
typedef T value_type;
|
|
|
|
bounded_queue( bounded_queue const& other) = delete;
|
|
bounded_queue & operator=( bounded_queue const& other) = delete;
|
|
|
|
bounded_queue( std::size_t wm);
|
|
|
|
bounded_queue( std::size_t hwm, std::size_t lwm);
|
|
|
|
bool is_closed() const;
|
|
void close();
|
|
|
|
bool is_empty();
|
|
bool is_full();
|
|
|
|
void push( T const& t);
|
|
void push( T && t);
|
|
template< typename Rep, typename Period >
|
|
queue_op_status wait_push( value_type const& va,
|
|
chrono::duration< Rep, Period > const& timeout_duration);
|
|
template< typename Rep, typename Period >
|
|
queue_op_status wait_push( value_type && va,
|
|
chrono::duration< Rep, Period > const& timeout_duration);
|
|
queue_op_status wait_push( value_type const& va,
|
|
clock_type::time_point const& timeout_time);
|
|
queue_op_status wait_push( value_type && va,
|
|
clock_type::time_point const& timeout_time);
|
|
queue_op_status try_push( value_type const& va);
|
|
queue_op_status try_push( value_type && va);
|
|
|
|
value_type value_pop();
|
|
template< typename Rep, typename Period >
|
|
queue_op_status wait_pop( value_type & va,
|
|
chrono::duration< Rep, Period > const& timeout_duration);
|
|
queue_op_status wait_pop( value_type & va,
|
|
clock_type::time_point const& timeout_time);
|
|
queue_op_status try_pop( value_type & va);
|
|
};
|
|
|
|
[heading Constructor]
|
|
|
|
bounded_queue( std::size_t wm);
|
|
bounded_queue( std::size_t hwm, std::size_t lwm);
|
|
|
|
[variablelist
|
|
[[Effects:] [Constructs an object of class `bounded_queue` which will contain
|
|
a maximum of `wm` items. The constructor with two arguments constructs an object
|
|
of class `bounded_queue` which will contain a high-watermark of `hwm` and a
|
|
low-watermark of `lwm` items.]]
|
|
[[Throws:] [Nothing.]]
|
|
]
|
|
|
|
[heading Member function `active()`]
|
|
|
|
bool active() const;
|
|
|
|
[variablelist
|
|
[[Effects:] [Return `true` if queue is still usable.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [The queue is usable by default.]]
|
|
]
|
|
|
|
[heading Member function `deactivate()`]
|
|
|
|
void deactivate();
|
|
|
|
[variablelist
|
|
[[Effects:] [Deactivates the queue. No values can be put after calling
|
|
`this->deactivate`. Fibers blocked in `this->take()` will return.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [`deactivate()` is like closing a pipe. It informs waiting receivers
|
|
that no more values will arrive.]]
|
|
]
|
|
|
|
[heading Member function `empty()`]
|
|
|
|
bool empty();
|
|
|
|
[variablelist
|
|
[[Effects:] [Returns `true` if the queue currently contains no data.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [This condition is transient. An `empty()` queue can become
|
|
non-empty.]]
|
|
[[Note:] [Oliver: wouldn't it make sense to have a corresponding `full()` method?]]
|
|
]
|
|
|
|
[heading Member function `put()`]
|
|
|
|
void put( T const& t);
|
|
|
|
[variablelist
|
|
[[Effects:] [Enqueues the value in the queue and wakes up a fiber waiting
|
|
for new data available from the queue. When the high water mark is reached, the
|
|
fiber putting the value will be supended until at least one item is
|
|
dequeued.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [interruption point]]
|
|
]
|
|
|
|
[heading Member function `take()`]
|
|
|
|
bool take( boost::optional< T > & va);
|
|
|
|
[variablelist
|
|
[[Effects:] [Dequeues a value from the queue. If no data is available from the
|
|
queue the fiber gets suspended until at least one new item is enqueued (return
|
|
value `true` and va contains dequeued value) or the queue gets deactivated and
|
|
the function returns `false`. Once the number of items remaining in the queue
|
|
drops below `lwm`, any fibers blocked on `put()` may resume.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [interruption point]]
|
|
]
|
|
|
|
[heading Member function `try_take()`]
|
|
|
|
bool try_take( boost::optional< T > & va);
|
|
|
|
[variablelist
|
|
[[Effects:] [Dequeues a value from the queue. If no data can be retrieved from
|
|
the queue at this moment, the function returns `false`. Otherwise it returns
|
|
`true` and `va` contains the dequeued value.]]
|
|
[[Throws:] [Nothing.]]
|
|
[[Note:] [A return value of `false` does not distinguish between `empty()` and
|
|
`(! active())`.]]
|
|
]
|
|
|
|
[endsect]
|