|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r83815 - trunk/libs/thread/doc
From: vicente.botet_at_[hidden]
Date: 2013-04-08 15:14:32
Author: viboes
Date: 2013-04-08 15:14:31 EDT (Mon, 08 Apr 2013)
New Revision: 83815
URL: http://svn.boost.org/trac/boost/changeset/83815
Log:
Thread: update ref doc for concurrent queues.
Text files modified:
trunk/libs/thread/doc/changes.qbk | 1
trunk/libs/thread/doc/future_ref.qbk | 6
trunk/libs/thread/doc/sync_queues_ref.qbk | 271 +++++++++++++++++++++++++++++----------
trunk/libs/thread/doc/thread.qbk | 2
4 files changed, 207 insertions(+), 73 deletions(-)
Modified: trunk/libs/thread/doc/changes.qbk
==============================================================================
--- trunk/libs/thread/doc/changes.qbk (original)
+++ trunk/libs/thread/doc/changes.qbk 2013-04-08 15:14:31 EDT (Mon, 08 Apr 2013)
@@ -25,6 +25,7 @@
[*New Features:]
* [@http://svn.boost.org/trac/boost/ticket/7285 #7285] C++11 compliance: Allow to pass movable arguments for call_once.
+* [@http://svn.boost.org/trac/boost/ticket/7445 #7445] Async: Add future<>.then
* [@http://svn.boost.org/trac/boost/ticket/7449 #7449] Synchro: Add a synchronized value class
[*Fixed Bugs:]
Modified: trunk/libs/thread/doc/future_ref.qbk
==============================================================================
--- trunk/libs/thread/doc/future_ref.qbk (original)
+++ trunk/libs/thread/doc/future_ref.qbk 2013-04-08 15:14:31 EDT (Mon, 08 Apr 2013)
@@ -686,10 +686,10 @@
then(F&& func); // EXTENSION
template<typename S, typename F>
__unique_future__<typename boost::result_of<F(__unique_future__&)>::type>
- then(S& scheduler, F&& func); // EXTENSION
+ then(S& scheduler, F&& func); // EXTENSION NOT_YET_IMPLEMENTED
template<typename F>
__unique_future__<typename boost::result_of<F(__unique_future__&)>::type>
- then(launch policy, F&& func); // EXTENSION
+ then(launch policy, F&& func); // EXTENSION NOT_YET_IMPLEMENTED
[variablelist
@@ -717,7 +717,7 @@
]]
-[[Returns:] [An object of type future<decltype(func(*this))> that refers to the shared state created by the continuation.]]
+[[Returns:] [An object of type future<typename boost::result_of<F(__unique_future__&)> that refers to the shared state created by the continuation.]]
[[Postconditions:] [
Modified: trunk/libs/thread/doc/sync_queues_ref.qbk
==============================================================================
--- trunk/libs/thread/doc/sync_queues_ref.qbk (original)
+++ trunk/libs/thread/doc/sync_queues_ref.qbk 2013-04-08 15:14:31 EDT (Mon, 08 Apr 2013)
@@ -17,17 +17,57 @@
[section:sync_queue_req Synchronized Queue Model]
-The BasicConcurrentQueue concept models .
-A type `Q` meets the BasicConcurrentQueue requirements if the following expressions are well-formed and have the specified semantics
+[section:bounded_unbounded Bounded-Unbounded Queues]
-* `q` denotes a value of type `Q`,
-* `e` denotes a value of type Q::value_type,
-* `u` denotes a value of type Q::size_type,
-* `lve` denotes a lvalue referece of type Q::value_type,
-* `rve` denotes a rvalue referece of type Q::value_type:
-* `spe` denotes a shared_ptr<Q::value_type>
+One of the major features of a concurrent queue is whether it has a bounded-unbounded capacity.
-Basic expressions
+[endsect]
+
+[section:locking Locking/Lock-free Queues]
+
+Locking queues can by nature block waiting for the queue to be non-empty or non-full.
+
+Lock-free queues will have some trouble waiting for the queue to be non-empty or non-full queues. These queues can not define operations such as push (and pull for bounded queues). That is, it could have blocking operations (presumably emulated with busy wait) but not waiting operations.
+
+[endsect]
+
+[section:closed Closed Queue]
+
+Threads using a queue for communication need some mechanism to signal when the queue is no longer needed. The usual approach is add an additional out-of-band signal. However, this approach suffers from the flaw that threads waiting on either full or empty queues need to be woken up when the queue is no longer needed. Rather than require an out-of-band signal, we chose to directly support such a signal in the queue itself, which considerably simplifies coding.
+
+To achieve this signal, a thread may close a queue. Once closed, no new elements may be pushed onto the queue. Push operations on a closed queue will either return queue_op_status::closed (when they have a queue_op_status return type), set the closed parameter if it has one or throw sync_queue::closed (when they do not). Elements already on the queue may be pulled off. When a queue is empty and closed, pull operations will either return queue_op_status::closed (when they have a status return), set the closed parameter if it has one or throw sync_queue::closed (when they do not).
+
+
+[endsect]
+
+[section:exception Concurrent Queues Throw specification]
+[section:locking Locking]
+
+All the functions are defined as if we had in addition to its specific Throw specification the following:
+
+[variablelist
+[[Throws:] [Any exception thrown by the internal locking.]]
+]
+
+[endsect]
+[section:bad_alloc Allocation]
+
+All the functions that allocate a resource are defined as if we had in addition to its specific Throw specification the following:
+
+[variablelist
+[[Throws:] [Any exception due to allocation errors.]]
+]
+
+[endsect]
+[endsect]
+
+[section:BasicConcurrentQueue Basic Concurrent Queue Operations]
+
+The essential solution to the problem of concurrent queuing is to shift to value-based operations, rather than reference-based operations.
+
+The BasicConcurrentQueue concept models the basic operations of a concurrent queue.
+
+A type `Q` meets the BasicConcurrentQueue requirements if the following expressions are well-formed and have the specified semantics
* Q::value_type
* Q::size_type
@@ -39,108 +79,117 @@
* `b = q.empty();`
* `u = q.size();`
-Non-waiting operations
+where
-* `b = q.try_push(e);`
-* `b = q.try_push(rve);`
-* `b = q.try_pull(lre);`
+* `q` denotes a value of type `Q`,
+* `e` denotes a value of type Q::value_type,
+* `u` denotes a value of type Q::size_type,
+* `lve` denotes a lvalue referece of type Q::value_type,
+* `rve` denotes a rvalue referece of type Q::value_type:
+* `spe` denotes a shared_ptr<Q::value_type>
-Non-blocking operations are provided by BlockingQueues
-* `b = q.try_push(nb, e);`
-* `b = q.try_push(nb, rve);`
-* `b = q.try_pull(nb, lre);`
+[section:push `q.push(e);`]
-Bounded queues add the following valid expressions
+[variablelist
-* `Q q(u);`
-* `b = q.full();`
-* `u = q.capacity();`
+[[Effects:] [Waits until the queue is not full (for bounded queues) and then push `e` to the queue copying it (this could need an allocation for unbounded queues).]]
-Closed queues
+[[Synchronization:] [Prior pull-like operations on the same object synchronizes with this operation.]]
-Threads using a queue for communication need some mechanism to signal when the queue is no longer needed. The usual approach is add an additional out-of-band signal. However, this approach suffers from the flaw that threads waiting on either full or empty queues need to be woken up when the queue is no longer needed. Rather than require an out-of-band signal, we chose to directly support such a signal in the queue itself, which considerably simplifies coding.
+[[Postcondition:] [`! q.empty()`.]]
-To achieve this signal, a thread may close a queue. Once closed, no new elements may be pushed onto the queue. Push operations on a closed queue will either return queue_op_status::closed (when they have a queue_op_status return type), set the closed parameter if it has one or throw sync_queue::closed (when they do not). Elements already on the queue may be popped off. When a queue is empty and closed, pop operations will either return queue_op_status::closed (when they have a status return) or throw queue_op_status::closed (when they do not).
+[[Return type:] [`void`.]]
-* `q.close();`
-* `b = q.closed();`
+[[Throws:] [If the queue was closed, throws sync_queue_is_closed. Any exception thrown by the copy of `e`.]]
-Basic expressions
+[[Exception safety:] [If an exception is thrown then the queue state is unmodified.]]
-* Q::value_type
-* `q.push(e,c);`
-* `q.push(rve,c);`
-* `q.pull(lre,c);`
-* `spe = q.ptr_pull(c);`
+]
-Non-waiting operations
+[endsect]
+[section:push_m `q.push(rve);`]
-* `b = q.try_push(e, c);`
-* `b = q.try_push(rve, c);`
-* `b = q.try_pull(lre, c);`
+[variablelist
-Non-blocking operations are provided by BlockingQueues
+[[Effects:] [Waits until the queue is not full (for bounded queues) and then push `e` to the queue moving it (this could need an allocation for unbounded queues).]]
-* `b = q.try_push(nb, e, c);`
-* `b = q.try_push(nb, rve, c);`
-* `b = q.try_pull(nb, lre, c);`
+[[Synchronization:] [Prior pull-like operations on the same object synchronizes with this operation.]]
+[[Postcondition:] [`! q.empty()`.]]
-[section:exception Blocking Queues Throw specification]
+[[Return type:] [`void`.]]
-All the functions that can throw are defined as if we had in addition to its specific Throw specification the following:
+[[Throws:] [If the queue is closed, throws sync_queue_is_closed. Any exception thrown by the copy of `e`.]]
+
+[[Exception safety:] [If an exception is thrown then the queue state is unmodified.]]
-[variablelist
-[[Throws:] [Any exception thrown by the internal locking.]]
]
[endsect]
-[section:exception2 Closed Queues Throw specification]
-
-All the modifier functions that have no a specific closed parameter can throw are defined as if we had in addition to its specific Throw specification the following:
+[section:pull_lv `q.pull(lve)`]
[variablelist
-[[Throws:] [Any exception thrown by the internal locking.]]
+
+[[Effects:] [Waits until the queue is not empty and then pull the element from the queue `q` and moves the pulled element into `lve` (this could need an allocation for unbounded queues).]]
+
+[[Synchronization:] [Prior pull-like operations on the same object synchronizes with this operation.]]
+
+[[Postcondition:] [`! q.full()`.]]
+
+[[Return type:] [`void`.]]
+
+[[Throws:] [Any exception thrown by the move of `e`.]]
+
+[[Exception safety:] [If an exception is thrown then the queue state is unmodified.]]
+
]
[endsect]
-
-[section:push `q.push(e);`]
+[section:pull `e = q.pull()`]
[variablelist
-[[Effects:] [Waits until the queue is not full (for bounded queues) and then push the `e` onto the queue copying it.]]
+[[Requires:] [Q::value_type is no throw copy movable. This is needed to ensure the exception safety.]]
+
+[[Effects:] [Waits until the queue is not empty and not closed. If the queue is empty and closed throws sync_queue_is_closed. Otherwise pull the element from the queue `q` and moves the pulled element.]]
[[Synchronization:] [Prior pull-like operations on the same object synchronizes with this operation.]]
-[[Postcondition:] [`! q.empty()`.]]
+[[Postcondition:] [`! q.full()`.]]
-[[Return type:] [`void`.]]
+[[Return type:] [`Q::value_type`.]]
-[[Throws:] [If the queue was closed, throws sync_queue_is_closed. Any exception thrown by the the copy of `e`.]]
+[[Return:] [The pulled element.]]
+
+[[Throws:] [Any exception thrown by the copy of `e`.]]
[[Exception safety:] [If an exception is thrown then the queue state is unmodified.]]
]
[endsect]
-[section:push_m `q.push(rve);`]
+
+[section:ptr_pull `spe = q.ptr_pull()`]
[variablelist
-[[Effects:] [Waits until the queue is not full (for bounded queues) and then push the `e` onto the queue moving it.]]
+[/[Requires:] [Q::value_type is no throw copy movable. This is needed to ensure the exception safety. ]]
+
+[[Effects:] [Waits until the queue is not empty and not closed. If the queue is empty and closed throws sync_queue_is_closed. Otherwise pull the element from the queue `q` and moves the pulled element into a shared_ptr.]]
[[Synchronization:] [Prior pull-like operations on the same object synchronizes with this operation.]]
-[[Postcondition:] [`! q.empty()`.]]
+[[Postcondition:] [`! q.full()`.]]
-[[Return type:] [`void`.]]
+[[Return type:] [`Q::value_type`.]]
-[[Throws:] [If the queue is closed, throws sync_queue_is_closed. Any exception thrown by the the copy of `e`.]]
+[[Return:] [A shared_ptr containing the pulled element.]]
+
+[[Throws:] [Any exception thrown by the move of `e`. Any exception throw when allocation resources are missing. ]]
[[Exception safety:] [If an exception is thrown then the queue state is unmodified.]]
@@ -148,11 +197,36 @@
[endsect]
+
+
+[endsect]
+
+[section:non_waaiting Non-waiting Concurrent Queue Operations]
+
+The ConcurrentQueue concept models a queue with .
+
+
+A type `Q` meets the ConcurrentQueue requirements if the following expressions are well-formed and have the specified semantics
+
+* `b = q.try_push(e);`
+* `b = q.try_push(rve);`
+* `b = q.try_pull(lre);`
+
+where
+
+* `q` denotes a value of type `Q`,
+* `e` denotes a value of type Q::value_type,
+* `u` denotes a value of type Q::size_type,
+* `lve` denotes a lvalue referece of type Q::value_type,
+* `rve` denotes a rvalue referece of type Q::value_type:
+* `spe` denotes a shared_ptr<Q::value_type>
+
+
[section:try_push `q.try_push(e);`]
[variablelist
-[[Effects:] [If the queue `q` is not full, push the `e` onto the queue copying it.]]
+[[Effects:] [If the queue `q` is not full, push the `e` to the queue copying it.]]
[[Synchronization:] [Prior pull-like operations on the same object synchronizes with this operation when the operation succeeds. ]]
@@ -162,7 +236,7 @@
[[Postcondition:] [If the call returns `true`, `! q.empty()`.]]
-[[Throws:] [If the queue is closed, throws sync_queue_is_closed. Any exception thrown by the the copy of `e`.]]
+[[Throws:] [If the queue is closed, throws sync_queue_is_closed. Any exception thrown by the copy of `e`.]]
[[Exception safety:] [If an exception is thrown then the queue state is unmodified.]]
@@ -183,37 +257,96 @@
[[Postcondition:] [If the call returns `true`, `! q.empty()`.]]
-[[Throws:] [If the queue is closed, throws sync_queue_is_closed. Any exception thrown by the the copy of `e`.]]
+[[Throws:] [If the queue is closed, throws sync_queue_is_closed. Any exception thrown by the copy of `e`.]]
[[Exception safety:] [If an exception is thrown then the queue state is unmodified.]]
]
[endsect]
-[section:pull `e = q.pull()`]
+[section:pull_lv `b = q.try_pull(lve)`]
[variablelist
-[[Requires:] [Q::value_type is no throw copy movable. This is needed to ensure the exception safety]]
-
-[[Effects:] [Waits until the queue is not empty and then pull the element from the queue `q` and moves the pulled element.]]
+[[Effects:] [Waits until the queue is not empty and then pull the element from the queue `q` and moves the pulled element into `lve` (this could need an allocation for unbounded queues).]]
[[Synchronization:] [Prior pull-like operations on the same object synchronizes with this operation.]]
[[Postcondition:] [`! q.full()`.]]
-[[Return type:] [`Q::value_type`.]]
+[[Return type:] [`bool`.]]
-[[Return:] [The pulled element.]]
+[[Return:] [If the queue `q` is full return `false`, otherwise return `true`;]]
-[[Throws:] [Any exception thrown by the copy of `e`.]]
+[[Throws:] [Any exception thrown by the move of `e`.]]
[[Exception safety:] [If an exception is thrown then the queue state is unmodified.]]
]
[endsect]
+[endsect]
+
+[section:non_blocking Non-blocking Concurrent Queue Operations]
+
+For cases when blocking for mutual exclusion is undesirable, we have non-blocking operations. The interface is the same as the try operations but is allowed to also return queue_op_status::busy in case the operation is unable to complete without blocking.
+
+Non-blocking operations are provided only for BlockingQueues
+* `b = q.try_push(nb, e);`
+* `b = q.try_push(nb, rve);`
+* `b = q.try_pull(nb, lre);`
+
+
+where
+
+* `q` denotes a value of type `Q`,
+* `e` denotes a value of type Q::value_type,
+* `u` denotes a value of type Q::size_type,
+* `lve` denotes a lvalue referece of type Q::value_type,
+* `rve` denotes a rvalue referece of type Q::value_type:
+* `spe` denotes a shared_ptr<Q::value_type>
+
+
+[endsect]
+
+[section:bounded Bounded Concurrent Queue Operations]
+
+Bounded queues add the following valid expressions
+
+* `Q q(u);`
+* `b = q.full();`
+* `u = q.capacity();`
+
+[endsect]
+
+[section:closed_op Closed Concurrent Queue Operations]
+
+
+* `q.close();`
+* `b = q.closed();`
+
+Basic expressions
+
+* `q.push(e,c);`
+* `q.push(rve,c);`
+* `q.pull(lre,c);`
+* `spe = q.ptr_pull(c);`
+
+Non-waiting operations
+
+* `b = q.try_push(e, c);`
+* `b = q.try_push(rve, c);`
+* `b = q.try_pull(lre, c);`
+
+Non-blocking operations are provided by BlockingQueues
+
+* `b = q.try_push(nb, e, c);`
+* `b = q.try_push(nb, rve, c);`
+* `b = q.try_pull(nb, lre, c);`
+
+
+[endsect]
[endsect]
Modified: trunk/libs/thread/doc/thread.qbk
==============================================================================
--- trunk/libs/thread/doc/thread.qbk (original)
+++ trunk/libs/thread/doc/thread.qbk 2013-04-08 15:14:31 EDT (Mon, 08 Apr 2013)
@@ -11,7 +11,7 @@
[version 4.1.0]
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
[copyright 2007-11 Anthony Williams]
- [copyright 2011-12 Vicente J. Botet Escriba]
+ [copyright 2011-13 Vicente J. Botet Escriba]
[purpose C++ Library for launching threads and synchronizing data between them]
[category text]
[license
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk