From fe8991b7fa4d757b672a68c8a9c8bc38f371a938 Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Sat, 15 Jun 2013 10:35:45 +0000 Subject: [PATCH] Thread: fix #8458 and update doc. [SVN r84792] --- build/Jamfile.v2 | 5 ++- doc/changes.qbk | 26 +++++++++++---- doc/compliance.qbk | 41 +++++++++++++---------- doc/configuration.qbk | 8 +++-- doc/external_locking.qbk | 49 ++++++++++++++++------------ doc/mutex_concepts.qbk | 20 ++++++------ doc/shared_mutex_ref.qbk | 18 +++++----- doc/sync_queues_ref.qbk | 7 ++++ doc/synchronized_value_ref.qbk | 7 ++++ include/boost/thread/strict_lock.hpp | 4 +-- 10 files changed, 115 insertions(+), 70 deletions(-) diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 16630080..2e8d52b8 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -263,8 +263,11 @@ rule requirements ( properties * ) result = no ; } } + result += BOOST_THREAD_DONT_USE_CHRONO ; + } else { + result += BOOST_THREAD_USES_CHRONO ; + result += /boost/chrono//boost_chrono ; } - result += BOOST_THREAD_DONT_USE_CHRONO ; if pgi in $(properties) || vacpp in $(properties) { diff --git a/doc/changes.qbk b/doc/changes.qbk index c826aec3..2945f4e4 100644 --- a/doc/changes.qbk +++ b/doc/changes.qbk @@ -1,6 +1,6 @@ [/ (C) Copyright 2007-11 Anthony Williams. - (C) Copyright 2011-12 Vicente J. Botet Escriba. + (C) Copyright 2011-13 Vicente J. Botet Escriba. 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). @@ -13,9 +13,14 @@ [*New Features:] -* [@http://svn.boost.org/trac/boost/ticket/8273 #8273] Add externally locked streams -* [@http://svn.boost.org/trac/boost/ticket/8274 #8274] Add concurrent queue -* [@http://svn.boost.org/trac/boost/ticket/8518 #8518] Sync: Add a latch class +* [@http://svn.boost.org/trac/boost/ticket/8273 #8273] Synchro:Add externally locked streams. +* [@http://svn.boost.org/trac/boost/ticket/8274 #8274] Synchro:Add concurrent queue. +* [@http://svn.boost.org/trac/boost/ticket/8515 #8515] Async: Add shared_future::then. +* [@http://svn.boost.org/trac/boost/ticket/8518 #8518] Synchro: Add a latch class. +* [@http://svn.boost.org/trac/boost/ticket/8615 #8615] Async: Replace make_future/make_shared_future by make_ready_future. +* [@http://svn.boost.org/trac/boost/ticket/8627 #8627] Async: Add future<>::unwrap. +* [@http://svn.boost.org/trac/boost/ticket/8677 #8677] Async: Add future<>::get_or. +* [@http://svn.boost.org/trac/boost/ticket/8678 #8678] Async: Add future<>::fallback_to. [*Fixed Bugs:] @@ -50,8 +55,10 @@ * [@http://svn.boost.org/trac/boost/ticket/8323 #8323] boost::thread::try_join_for/try_join_until may block indefinitely due to a combination of problems in Boost.Thread and Boost.Chrono * [@http://svn.boost.org/trac/boost/ticket/8337 #8337] The internal representation of "std::string(this->code()->message())" escapes, but is destroyed when it exits scope. * [@http://svn.boost.org/trac/boost/ticket/8371 #8371] C++11 once_flag enabled when constexpr is not available +* [@http://svn.boost.org/trac/boost/ticket/8422 #8422] Assertion in win32::WaitForSingleObject() * [@http://svn.boost.org/trac/boost/ticket/8443 #8443] Header file inclusion order may cause crashes * [@http://svn.boost.org/trac/boost/ticket/8451 #8451] Missing documented function 'boost::scoped_thread::joinable' +* [@http://svn.boost.org/trac/boost/ticket/8458 #8458] -DBOOST_THREAD_DONT_USE_CHRONO in thread.obj.rsp but not explicitly set * [@http://svn.boost.org/trac/boost/ticket/8530 #8530] [Coverity] Unused variable thread_handle, uninitialized variable cond_mutex in thread/pthread/thread_data.hpp * [@http://svn.boost.org/trac/boost/ticket/8550 #8550] static linking of Boost.Thread with an MFC-Dll * [@http://svn.boost.org/trac/boost/ticket/8576 #8576] "sur parolle" should be "sur parole". @@ -60,6 +67,7 @@ * [@http://svn.boost.org/trac/boost/ticket/8645 #8645] Typo in Strict lock definition * [@http://svn.boost.org/trac/boost/ticket/8671 #8671] promise: set_..._at_thread_exit * [@http://svn.boost.org/trac/boost/ticket/8672 #8672] future<>::then(void()) doesn't works +* [@http://svn.boost.org/trac/boost/ticket/8674 #8674] Futures as local named objects can't be returned with implicit move. [heading Version 4.0.0 - boost 1.53] @@ -411,7 +419,7 @@ The following features will be included in next releases. * [@http://svn.boost.org/trac/boost/ticket/8273 #8273] Add externally locked streams * [@http://svn.boost.org/trac/boost/ticket/8274 #8274] Add concurrent queue * [@http://svn.boost.org/trac/boost/ticket/8518 #8518] Sync: Add a latch class - * [@http://svn.boost.org/trac/boost/ticket/XXXX #XXXX] Sync: Add a completion_latch class + * [@http://svn.boost.org/trac/boost/ticket/8519 #8519] Sync: Add a completion_latch class * [@http://svn.boost.org/trac/boost/ticket/8513 #8513] Async: Add a basic thread_pool executor. * [@http://svn.boost.org/trac/boost/ticket/8514 #8514] Async: Add a thread_pool executor with work stealing. @@ -420,11 +428,15 @@ The following features will be included in next releases. * [@http://svn.boost.org/trac/boost/ticket/7446 #7446] Async: Add when_any. * [@http://svn.boost.org/trac/boost/ticket/7447 #7447] Async: Add when_all. * [@http://svn.boost.org/trac/boost/ticket/7448 #7448] Async: Add async taking a scheduler parameter. - * [@http://svn.boost.org/trac/boost/ticket/8515 #8515] Async: Add shared_future::then + * [@http://svn.boost.org/trac/boost/ticket/8515 #8515] Async: Add shared_future::then. * [@http://svn.boost.org/trac/boost/ticket/8516 #8516] Async: Add future/shared_future::then taking a scheduler as parameter. - * [@http://svn.boost.org/trac/boost/ticket/8517 #8517] Async: Add a variadic future/shared_future::then + * [@http://svn.boost.org/trac/boost/ticket/8627 #8627] Async: Add future<>::unwrap. +# And some additional extensions related to futures as: + * [@http://svn.boost.org/trac/boost/ticket/8677 #8677] Async: Add future<>::get_or. + * [@http://svn.boost.org/trac/boost/ticket/8678 #8678] Async: Add future<>::fallback_to. + * [@http://svn.boost.org/trac/boost/ticket/8517 #8517] Async: Add a variadic shared_future::then. [endsect] diff --git a/doc/compliance.qbk b/doc/compliance.qbk index 015e3a8c..8f176fe9 100644 --- a/doc/compliance.qbk +++ b/doc/compliance.qbk @@ -53,7 +53,7 @@ [[30.4.2.2.1] [unique_lock constructors, destructor, and assignment] [Yes] [-] [-]] [[30.4.2.2.2] [unique_lock locking] [Yes] [-] [-]] [[30.4.2.2.3] [unique_lock modifiers] [Yes] [-] [-]] - [[30.4.2.2.4] [unique_lock observers] [Yes] [] [-]] + [[30.4.2.2.4] [unique_lock observers] [Yes] [ - ] [-]] [[30.4.3] [Generic locking algorithms] [Partial] [variadic] [#6227]] [[30.4.4] [Call once] [Yes] [-] [-]] [[30.4.4.1] [Struct once_flag] [Yes] [-] [-]] @@ -107,6 +107,7 @@ [section:latch C++ Latches and Barriers] [note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3600.html N3659 C++ Latches and Barriers]] +[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3666.html N3659 C++ Latches and Barriers]] [table C++ Latches and Barriers Conformance [[Section] [Description] [Status] [Comments]] @@ -125,10 +126,10 @@ [[X.1.1] [Basic Operations] [Partial] [ - ]] [[X.1.1.1] [push] [yes] [ - ]] [[X.1.1.2] [value_pop] [no] [ renamed pull with two flavors + a ptr_pull that returns a sharted_ptr<>. ]] - [[X.1.2] [Non-waiting operations] [] [ - ]] + [[X.1.2] [Non-waiting operations] [ - ] [ - ]] [[X.1.2.1] [try_push] [Partial] [ return bool instead ]] [[X.1.2.2] [try_pop] [Partial] [ renamed try_pull, returns null ]] - [[X.1.3] [Non-blocking operations] [] [ - ]] + [[X.1.3] [Non-blocking operations] [ - ] [ - ]] [[X.1.3.1] [nonblocking_push] [Partial] [ renamed try_push(no_block, ]] [[X.1.3.2] [nonblocking_pop] [Partial] [ renamed try_pop(no_block, ]] [[X.1.4] [Push-front operations] [No] [ - ]] @@ -148,15 +149,15 @@ [[X.1.9] [Exception Handling] [Yes?] [ - ]] [[X.1.10] [Queue Ordering] [Yes?] [ - ]] [[X.1.11] [Lock-Free Implementations] [No] [ waiting to stabilize the lock-based interface. Will use Boost.LockFree once it is Move aware. ]] - [[X.2] [Concrete queues] [Partial] [ ]] + [[X.2] [Concrete queues] [Partial] [ - ]] [[X.2.1] [Locking Buffer Queue] [Partial] [ classes sync_queue and a sync_bounded_queue. ]] - [[X.2.1] [Lock-Free Buffer Queue] [No] [ ]] - [[X.3] [Additional Conceptual Tools] [No] [ ]] - [[X.3.1] [Fronts and Backs] [No] [ ]] - [[X.3.2] [Streaming Iterators] [No] [ ]] - [[X.3.3] [Storage Iterators] [No] [ ]] - [[X.3.4] [Binary Interfaces] [No] [ ]] - [[X.3.4] [Managed Indirection] [No] [ ]] + [[X.2.1] [Lock-Free Buffer Queue] [No] [ - ]] + [[X.3] [Additional Conceptual Tools] [No] [ - ]] + [[X.3.1] [Fronts and Backs] [No] [ - ]] + [[X.3.2] [Streaming Iterators] [No] [ - ]] + [[X.3.3] [Storage Iterators] [No] [ - ]] + [[X.3.4] [Binary Interfaces] [No] [ - ]] + [[X.3.4] [Managed Indirection] [No] [ - ]] ] [endsect] @@ -192,17 +193,18 @@ While Boost.Thread implementation of executors would not use dynamic polymorphis [section:async A Standardized Representation of Asynchronous Operations] [note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3558.pdf N3558 A Standardized Representation of Asynchronous Operations]] +[note These functions are based on the [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3634.pdf [*N3634 - Improvements to std::future and related APIs]] C++1y proposal by N. Gustafsson, A. Laksberg, H. Sutter, S. Mithani.] -[table A Standardized Representation of Asynchronous Operations Conformance +[table Improvements to std::future and related APIs] [[Section] [Description] [Status] [Comments]] [[30.6.6] [Class template future] [Partial] [ - ]] [[30.6.6.1] [then] [Partial] [ executor interface missing #8516 ]] - [[30.6.6.2] [unwrap] [No] [ #XXXX ]] - [[30.6.6.3] [ready] [yes] [ is_ready ]] + [[30.6.6.2] [unwrap] [Yes] [ - ]] + [[30.6.6.3] [ready] [Partial] [ is_ready ]] [[30.6.7] [Class template shared_future] [Partial] [ - ]] - [[30.6.7.1] [then] [No] [ #8515 ]] + [[30.6.7.1] [then] [Yes] [ executor interface missing #8516 ]] [[30.6.7.2] [unwrap] [No] [ #XXXX ]] - [[30.6.7.3] [ready] [Yes] [ is_ready ]] + [[30.6.7.3] [ready] [Partial] [ is_ready ]] [[30.6.X] [Function template when_any] [No] [ #7446 ]] [[30.6.X] [Function template when_all] [No] [ #7447 ]] [[30.6.X] [Function template make_ready_future] [Yes] [ - ]] @@ -211,11 +213,11 @@ While Boost.Thread implementation of executors would not use dynamic polymorphis [endsect] -[section:stream_mutex C++ Stream Mutexes] +[section:stream_mutex C++ Stream Mutexes - C++ Stream Guards] While Boost.Thread implementation of stream mutexes differ in the approach, it is worth comparing with the current trend on the standard. -[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3535.html N3535 - C++ Stream Mutexes]] +[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3535.html N3535 - C++ Stream Mutexes]. This has been replaced already by N3678 - C++ Stream Guards.] [table C++ C++ Stream MutexesConformance [[Section] [Description] [Status] [Comments]] @@ -234,6 +236,9 @@ While Boost.Thread implementation of stream mutexes differ in the approach, it i [[X.4] [Predefined Objects] [No] [.]] ] +[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3678.html N3678 - C++ Stream Guards]] + + [endsect] diff --git a/doc/configuration.qbk b/doc/configuration.qbk index 206eebad..35528858 100644 --- a/doc/configuration.qbk +++ b/doc/configuration.qbk @@ -11,7 +11,7 @@ [table Default Values for Configurable Features [[Feature] [Anti-Feature] [V2] [V3] [V4] ] - [[USES_CHRONO] [DONT_USE_CHRONO] [YES] [YES] [YES] ] + [[USES_CHRONO] [DONT_USE_CHRONO] [YES/NO] [YES/NO] [YES/NO] ] [[PROVIDES_INTERRUPTIONS] [DONT_PROVIDE_INTERRUPTIONS] [YES] [YES] [YES] ] [[THROW_IF_PRECONDITION_NOT_SATISFIED] [-] [NO] [NO] [NO] ] @@ -31,7 +31,7 @@ [[PROVIDES_ONCE_CXX11] [DONT_PROVIDE_ONCE_CXX11] [NO] [YES] [YES] ] [[USES_MOVE] [DONT_USE_MOVE] [NO] [YES] [YES] ] - [[USES_DATETIME] [DONT_USE_DATETIME] [YES] [YES] [YES/NO] ] + [[USES_DATETIME] [DONT_USE_DATETIME] [YES/NO] [YES/NO] [YES/NO] ] [[PROVIDES_THREAD_EQ] [DONT_PROVIDE_THREAD_EQ] [YES] [YES] [NO] ] [[PROVIDES_CONDITION] [DONT_PROVIDE_CONDITION] [YES] [YES] [NO] ] [[PROVIDES_NESTED_LOCKS] [DONT_PROVIDE_NESTED_LOCKS] [YES] [YES] [NO] ] @@ -47,6 +47,8 @@ Boost.Thread uses by default Boost.Chrono for the time related functions and define `BOOST_THREAD_USES_CHRONO` if `BOOST_THREAD_DONT_USE_CHRONO` is not defined. The user should define `BOOST_THREAD_DONT_USE_CHRONO` for compilers that don't work well with Boost.Chrono. +[warning When defined BOOST_THREAD_PLATFORM_WIN32 BOOST_THREAD_USES_CHRONO is defined independently of user settings.] + [endsect] @@ -72,7 +74,7 @@ The Boost.DateTime time related functions introduced in Boost 1.35.0, using the When `BOOST_THREAD_VERSION<=3` && defined BOOST_THREAD_PLATFORM_PTHREAD define `BOOST_THREAD_DONT_USE_DATETIME` if you don't want to use Boost.DateTime related interfaces. When `BOOST_THREAD_VERSION>3` && defined BOOST_THREAD_PLATFORM_PTHREAD define `BOOST_THREAD_USES_DATETIME` if you want to use Boost.DateTime related interfaces. -When defined BOOST_THREAD_PLATFORM_WIN32 BOOST_THREAD_USES_DATETIME is defined by default. +[warning When defined BOOST_THREAD_PLATFORM_WIN32 BOOST_THREAD_USES_DATETIME is defined independently of user settings.] [endsect] diff --git a/doc/external_locking.qbk b/doc/external_locking.qbk index ed9e7cc9..9f78d68c 100644 --- a/doc/external_locking.qbk +++ b/doc/external_locking.qbk @@ -182,10 +182,12 @@ For now, let's make a couple of enhancements to the `lock_guard` class template We'll call the enhanced version `strict_lock`. Essentially, a `strict_lock`'s role is only to live on the stack as an automatic variable. `strict_lock` must adhere to a non-copy and non-alias policy. `strict_lock` disables copying by making the copy constructor and the assignment operator private. -While we're at it, let's disable operator new and operator delete; +While we're at it, let's disable operator new and operator delete. + +[/ `strict_lock` are not intended to be allocated on the heap. `strict_lock` avoids aliasing by using a slightly less orthodox and less well-known technique: disable address taking. - +] template class strict_lock { @@ -229,6 +231,7 @@ Silence can be sometimes louder than words-what's forbidden to do with a `strict // ok, Bar takes a reference to strict_lock extern void Bar(strict_lock&); +[/ * You cannot allocate a `strict_lock` on the heap. However, you still can put `strict_lock`s on the heap if they're members of a class. strict_lock* pL = @@ -250,8 +253,9 @@ Silence can be sometimes louder than words-what's forbidden to do with a `strict strict_lock& rAlias = myLock; // ok Fortunately, references don't engender as bad aliasing as pointers because they're much less versatile (references cannot be copied or reseated). - -* You can even make `strict_lock` final; that is, impossible to derive from. This task is left in the form of an exercise to the reader. +] +[/* You can even make `strict_lock` final; that is, impossible to derive from. This task is left in the form of an exercise to the reader. +] All these rules were put in place with one purpose-enforcing that owning a `strict_lock` is a reasonably strong guarantee that @@ -398,8 +402,8 @@ The solution is to use a little bridge template `externally_locked` that control T& get(strict_lock& lock) { - #ifndef BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_SAME // define BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_SAME if you don't want to check locker check the same lockable - if (!lock.is_locking(&lockable_)) throw lock_error(); run time check throw if not locks the same + #ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED + if (!lock.owns_lock(&lockable_)) throw lock_error(); run time check throw if not locks the same #endif return obj_; } @@ -478,7 +482,7 @@ We need a way to transfer the ownership from the `unique_lock` to a `strict_lock In order to make this code compilable we need to store either a Lockable or a `unique_lock` reference depending on the constructor. Store which kind of reference we have stored,and in the destructor call either to the Lockable `unlock` or restore the ownership. -This seams too complicated to me. Another possibility is to define a nested strict lock class. The drawback is that instead of having only one strict lock we have two and we need either to duplicate every function taking a `strict\_lock` or make these function templates functions. The problem with template functions is that we don't profit anymore of the C++ type system. We must add some static metafunction that check that the Locker parameter is a strict lock. The problem is that we can not really check this or can we?. The `is_strict_lock` metafunction must be specialized by the strict lock developer. We need to belive it "sur parole". The advantage is that now we can manage with more than two strict locks without changing our code. Ths is really nice. +This seams too complicated to me. Another possibility is to define a nested strict lock class. The drawback is that instead of having only one strict lock we have two and we need either to duplicate every function taking a `strict_lock` or make these function templates functions. The problem with template functions is that we don't profit anymore of the C++ type system. We must add some static metafunction that check that the Locker parameter is a strict lock. The problem is that we can not really check this or can we?. The `is_strict_lock` metafunction must be specialized by the strict lock developer. We need to belive it "sur parole". The advantage is that now we can manage with more than two strict locks without changing our code. Ths is really nice. Now we need to state that both classes are `strict_lock`s. @@ -508,7 +512,7 @@ First `nested_strict_lock` class will store on a temporary lock the `Locker`, an : lock_(lock) // Store reference to locker , tmp_lock_(lock.move()) // Move ownership to temporaty locker { - #ifndef BOOST_THREAD_STRCIT_LOCKER_DONT_CHECK_OWNERSHIP // Define BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_OWNERSHIP if you don't want to check locker ownership + #ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED if (tmp_lock_.mutex()==0) { lock_=tmp_lock_.move(); // Rollback for coherency purposes throw lock_error(); @@ -519,24 +523,29 @@ First `nested_strict_lock` class will store on a temporary lock the `Locker`, an ~nested_strict_lock() { lock_=tmp_lock_.move(); // Move ownership to nesting locker } - typedef bool (nested_strict_lock::*bool_type)() const; - operator bool_type() const { return &nested_strict_lock::owns_lock; } - bool operator!() const { return false; } bool owns_lock() const { return true; } - const lockable_type* mutex() const { return tmp_lock_.mutex(); } - bool is_locking(lockable_type* l) const { return l==mutex(); } + lockable_type* mutex() const { return tmp_lock_.mutex(); } + bool owns_lock(lockable_type* l) const { return l==mutex(); } - BOOST_ADRESS_OF_DELETE(nested_strict_lock) - BOOST_HEAP_ALLOCATEION_DELETE(nested_strict_lock) - BOOST_DEFAULT_CONSTRUCTOR_DELETE(nested_strict_lock) 8 - BOOST_COPY_CONSTRUCTOR_DELETE(nested_strict_lock) 9 - BOOST_COPY_ASSIGNEMENT_DELETE(nested_strict_lock) 10 private: Locker& lock_; Locker tmp_lock_; }; +[/ + typedef bool (nested_strict_lock::*bool_type)() const; + operator bool_type() const { return &nested_strict_lock::owns_lock; } + bool operator!() const { return false; } + + BOOST_ADRESS_OF_DELETE(nested_strict_lock) + BOOST_HEAP_ALLOCATEION_DELETE(nested_strict_lock) + BOOST_DEFAULT_CONSTRUCTOR_DELETE(nested_strict_lock) + BOOST_COPY_CONSTRUCTOR_DELETE(nested_strict_lock) + BOOST_COPY_ASSIGNEMENT_DELETE(nested_strict_lock) + +] + The `externally_locked` get function is now a template function taking a Locker as parameters instead of a `strict_lock`. We can add test in debug mode that ensure that the Lockable object is locked. @@ -554,8 +563,8 @@ We can add test in debug mode that ensure that the Lockable object is locked. #ifndef BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_OWNERSHIP // define BOOST_THREAD_EXTERNALLY_LOCKED_NO_CHECK_OWNERSHIP if you don't want to check locker ownership if (! lock ) throw lock_error(); // run time check throw if no locked #endif - #ifndef BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_SAME - if (!lock.is_locking(&lockable_)) throw lock_error(); + #ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED + if (!lock.owns_lock(&lockable_)) throw lock_error(); #endif return obj_; } diff --git a/doc/mutex_concepts.qbk b/doc/mutex_concepts.qbk index 62d88df1..b9fbe2b1 100644 --- a/doc/mutex_concepts.qbk +++ b/doc/mutex_concepts.qbk @@ -344,14 +344,14 @@ reached. If the specified time has already passed, behaves as __try_lock_ref__.] [endsect] -[section:shared_lockable `SharedLockable` Concept -- EXTENSION] +[section:shared_lockable `SharedLockable` Concept -- C++14] // #include namespace boost { template - class SharedLockable; // EXTENSION + class SharedLockable; // C++14 } @@ -1205,9 +1205,9 @@ The following classes are models of `StrictLock`: template void swap(unique_lock & lhs, unique_lock & rhs); template - class shared_lock; // EXTENSION + class shared_lock; // C++14 template - void swap(shared_lock& lhs,shared_lock& rhs); // EXTENSION + void swap(shared_lock& lhs,shared_lock& rhs); // C++14 template class upgrade_lock; // EXTENSION template @@ -1235,13 +1235,13 @@ The following classes are models of `StrictLock`: unique_lock(Lockable& m_,try_to_lock_t); #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION - unique_lock(shared_lock&& sl, try_to_lock_t) + unique_lock(shared_lock&& sl, try_to_lock_t); // C++14 template unique_lock(shared_lock&& sl, - const chrono::time_point& abs_time); + const chrono::time_point& abs_time); // C++14 template unique_lock(shared_lock&& sl, - const chrono::duration& rel_time) + const chrono::duration& rel_time); // C++14 #endif template @@ -1253,7 +1253,7 @@ The following classes are models of `StrictLock`: unique_lock(unique_lock const&) = delete; unique_lock& operator=(unique_lock const&) = delete; unique_lock(unique_lock&& other) noexcept; - explicit unique_lock(upgrade_lock&& other) noexcept; + explicit unique_lock(upgrade_lock&& other) noexcept; // EXTENSION unique_lock& operator=(unique_lock&& other) noexcept; @@ -1583,7 +1583,7 @@ __owns_lock_ref__ returns `false`.]] [endsect] -[section:shared_lock Class template `shared_lock` - EXTENSION] +[section:shared_lock Class template `shared_lock` - C++14] // #include // #include @@ -1621,7 +1621,7 @@ __owns_lock_ref__ returns `false`.]] void unlock(); // Conversion from upgrade locking - explicit shared_lock(upgrade_lock && other); + explicit shared_lock(upgrade_lock && other); // EXTENSION // Conversion from exclusive locking explicit shared_lock(unique_lock && other); diff --git a/doc/shared_mutex_ref.qbk b/doc/shared_mutex_ref.qbk index 3d26a12b..d151b0a4 100644 --- a/doc/shared_mutex_ref.qbk +++ b/doc/shared_mutex_ref.qbk @@ -5,7 +5,7 @@ http://www.boost.org/LICENSE_1_0.txt). ] -[section:shared_mutex Class `shared_mutex` -- EXTENSION] +[section:shared_mutex Class `shared_mutex` -- C++14] #include @@ -36,18 +36,18 @@ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 // use upgrade_mutex instead. - void lock_upgrade(); - void unlock_upgrade(); + void lock_upgrade(); // EXTENSION + void unlock_upgrade(); // EXTENSION - void unlock_upgrade_and_lock(); - void unlock_and_lock_upgrade(); - void unlock_and_lock_shared(); - void unlock_upgrade_and_lock_shared(); + void unlock_upgrade_and_lock(); // EXTENSION + void unlock_and_lock_upgrade(); // EXTENSION + void unlock_and_lock_shared(); // EXTENSION + void unlock_upgrade_and_lock_shared(); // EXTENSION #endif #if defined BOOST_THREAD_USES_DATETIME - bool timed_lock_shared(system_time const& timeout); - bool timed_lock(system_time const& timeout); + bool timed_lock_shared(system_time const& timeout); // DEPRECATED + bool timed_lock(system_time const& timeout); // DEPRECATED #endif }; diff --git a/doc/sync_queues_ref.qbk b/doc/sync_queues_ref.qbk index 4e3f7263..da8fe833 100644 --- a/doc/sync_queues_ref.qbk +++ b/doc/sync_queues_ref.qbk @@ -1,3 +1,10 @@ +[/ + / Copyright (c) 2013 Vicente J. Botet Escriba + / + / 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:synchronized_queues Synchronized Queues -- EXPERIMENTAL] [warning These features are experimental and subject to change in future versions. There are not too much tests yet, so it is possible that you can find out some trivial bugs :(] diff --git a/doc/synchronized_value_ref.qbk b/doc/synchronized_value_ref.qbk index 5dc235a6..20b304c8 100644 --- a/doc/synchronized_value_ref.qbk +++ b/doc/synchronized_value_ref.qbk @@ -1,3 +1,10 @@ +[/ + / Copyright (c) 2013 Vicente J. Botet Escriba + / + / 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:synchronized_value_ref Reference ] diff --git a/include/boost/thread/strict_lock.hpp b/include/boost/thread/strict_lock.hpp index 81aca62c..93b7b1e7 100644 --- a/include/boost/thread/strict_lock.hpp +++ b/include/boost/thread/strict_lock.hpp @@ -77,7 +77,7 @@ namespace boost /** * @return the owned mutex. */ - const mutex_type* mutex() const BOOST_NOEXCEPT + mutex_type* mutex() const BOOST_NOEXCEPT { return &mtx_; } @@ -182,7 +182,7 @@ namespace boost /** * return @c the owned mutex. */ - const mutex_type* mutex() const BOOST_NOEXCEPT + mutex_type* mutex() const BOOST_NOEXCEPT { return tmp_lk_.mutex(); }