2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-11 12:12:12 +00:00

Thread: merge from trunk upgrade_to_unique_lock::mutex() + doc typos + BOOST_THREAD_USES_ATOMIC doc + synchronized _value call + rename wait_until params.

[SVN r85603]
This commit is contained in:
Vicente J. Botet Escriba
2013-09-08 09:50:12 +00:00
parent 3fb971386a
commit 73f5c060ca
11 changed files with 276 additions and 48 deletions

View File

@@ -57,7 +57,8 @@ namespace boost
struct void_functor_barrier_reseter
{
unsigned int size_;
void_completion_function fct_;template <typename F>
void_completion_function fct_;
template <typename F>
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
void_functor_barrier_reseter(unsigned int size, BOOST_THREAD_RV_REF(F) funct)
: size_(size), fct_(boost::move(funct))
@@ -90,7 +91,7 @@ namespace boost
}
class barrier
{
static inline unsigned int check(unsigned int count)
static inline unsigned int check_counter(unsigned int count)
{
if (count == 0) boost::throw_exception(
thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero."));
@@ -104,7 +105,7 @@ namespace boost
BOOST_THREAD_NO_COPYABLE( barrier)
explicit barrier(unsigned int count) :
m_count(check(count)), m_generation(0), fct_(thread_detail::default_barrier_reseter(count))
m_count(check_counter(count)), m_generation(0), fct_(thread_detail::default_barrier_reseter(count))
{
}
@@ -120,7 +121,7 @@ namespace boost
typename is_void<typename result_of<F>::type>::type, dummy*
>::type=0
)
: m_count(check(count)),
: m_count(check_counter(count)),
m_generation(0),
fct_(thread_detail::void_functor_barrier_reseter(count,
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
@@ -145,7 +146,7 @@ namespace boost
typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
>::type=0
)
: m_count(check(count)),
: m_count(check_counter(count)),
m_generation(0),
fct_(
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
@@ -158,7 +159,7 @@ namespace boost
}
barrier(unsigned int count, void(*funct)()) :
m_count(check(count)), m_generation(0),
m_count(check_counter(count)), m_generation(0),
fct_(funct
? thread_detail::size_completion_function(thread_detail::void_fct_ptr_barrier_reseter(count, funct))
: thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count))
@@ -166,7 +167,7 @@ namespace boost
{
}
barrier(unsigned int count, unsigned int(*funct)()) :
m_count(check(count)), m_generation(0),
m_count(check_counter(count)), m_generation(0),
fct_(funct
? thread_detail::size_completion_function(funct)
: thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count))

View File

@@ -1112,6 +1112,10 @@ namespace boost
{
return exclusive.owns_lock();
}
Mutex* mutex() const BOOST_NOEXCEPT
{
return exclusive.mutex();
}
};
BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
@@ -1187,7 +1191,7 @@ private unique_lock<Mutex>
{
return base::owns_lock();
}
Mutex* mutex() const
Mutex* mutex() const BOOST_NOEXCEPT
{
return base::mutex();
}

View File

@@ -200,15 +200,15 @@ namespace boost
#if defined BOOST_THREAD_USES_DATETIME
template<typename lock_type>
bool timed_wait(lock_type& m,boost::system_time const& wait_until)
bool timed_wait(lock_type& m,boost::system_time const& abs_time)
{
struct timespec const timeout=detail::to_timespec(wait_until);
struct timespec const timeout=detail::to_timespec(abs_time);
return do_wait_until(m, timeout);
}
template<typename lock_type>
bool timed_wait(lock_type& m,xtime const& wait_until)
bool timed_wait(lock_type& m,xtime const& abs_time)
{
return timed_wait(m,system_time(wait_until));
return timed_wait(m,system_time(abs_time));
}
template<typename lock_type,typename duration_type>
@@ -218,20 +218,20 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred)
{
while (!pred())
{
if(!timed_wait(m, wait_until))
if(!timed_wait(m, abs_time))
return pred();
}
return true;
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,xtime const& wait_until,predicate_type pred)
bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred)
{
return timed_wait(m,system_time(wait_until),pred);
return timed_wait(m,system_time(abs_time),pred);
}
template<typename lock_type,typename duration_type,typename predicate_type>

View File

@@ -98,21 +98,21 @@ namespace boost
#if defined BOOST_THREAD_USES_DATETIME
inline bool timed_wait(
unique_lock<mutex>& m,
boost::system_time const& wait_until)
boost::system_time const& abs_time)
{
#if defined BOOST_THREAD_WAIT_BUG
struct timespec const timeout=detail::to_timespec(wait_until + BOOST_THREAD_WAIT_BUG);
struct timespec const timeout=detail::to_timespec(abs_time + BOOST_THREAD_WAIT_BUG);
return do_wait_until(m, timeout);
#else
struct timespec const timeout=detail::to_timespec(wait_until);
struct timespec const timeout=detail::to_timespec(abs_time);
return do_wait_until(m, timeout);
#endif
}
bool timed_wait(
unique_lock<mutex>& m,
xtime const& wait_until)
xtime const& abs_time)
{
return timed_wait(m,system_time(wait_until));
return timed_wait(m,system_time(abs_time));
}
template<typename duration_type>
@@ -126,11 +126,11 @@ namespace boost
template<typename predicate_type>
bool timed_wait(
unique_lock<mutex>& m,
boost::system_time const& wait_until,predicate_type pred)
boost::system_time const& abs_time,predicate_type pred)
{
while (!pred())
{
if(!timed_wait(m, wait_until))
if(!timed_wait(m, abs_time))
return pred();
}
return true;
@@ -139,9 +139,9 @@ namespace boost
template<typename predicate_type>
bool timed_wait(
unique_lock<mutex>& m,
xtime const& wait_until,predicate_type pred)
xtime const& abs_time,predicate_type pred)
{
return timed_wait(m,system_time(wait_until),pred);
return timed_wait(m,system_time(abs_time),pred);
}
template<typename duration_type,typename predicate_type>

View File

@@ -26,10 +26,12 @@
//#endif
#if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics.
#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics on C++98 compilers.
#include <functional>
#endif
#include <boost/utility/result_of.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
@@ -593,8 +595,6 @@ namespace boost
boost::swap(value_, rhs);
}
/**
* Essentially calling a method obj->foo(x, y, z) calls the method foo(x, y, z) inside a critical section as
* long-lived as the call itself.
@@ -613,14 +613,81 @@ namespace boost
return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
}
/**
* Call function on a locked block.
*
* @requires fct(value_) is well formed.
*
* Example
* void fun(synchronized_value<vector<int>> & v) {
* v ( [](vector<int>> & vec)
* {
* vec.push_back(42);
* assert(vec.back() == 42);
* } );
* }
*/
template <typename F>
inline
typename boost::result_of<F(value_type&)>::type
operator()(BOOST_THREAD_RV_REF(F) fct)
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
template <typename F>
inline
typename boost::result_of<F(value_type const&)>::type
operator()(BOOST_THREAD_RV_REF(F) fct) const
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename F>
inline
typename boost::result_of<F(value_type&)>::type
operator()(F const & fct)
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
template <typename F>
inline
typename boost::result_of<F(value_type const&)>::type
operator()(F const & fct) const
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
template <typename R>
inline
R operator()(R(*fct)(value_type&))
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
template <typename R>
inline
R operator()(R(*fct)(value_type const&)) const
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
#endif
/**
* The synchronize() factory make easier to lock on a scope.
* As discussed, operator-> can only lock over the duration of a call, so it is insufficient for complex operations.
* With synchronize() you get to lock the object in a scoped and to directly access the object inside that scope.
*
* Example
* void fun(synchronized_value<vector<int>> & vec) {
* auto&& vec=vec.synchronize();
* void fun(synchronized_value<vector<int>> & v) {
* auto&& vec=v.synchronize();
* vec.push_back(42);
* assert(vec.back() == 42);
* }
@@ -880,9 +947,9 @@ namespace boost
//Hash support
template <class T> struct hash;
template <typename T, typename L>
struct hash<synchronized_value<T,L> >;
// template <class T> struct hash;
// template <typename T, typename L>
// struct hash<synchronized_value<T,L> >;
// Comparison with T
template <typename T, typename L>