mirror of
https://github.com/boostorg/thread.git
synced 2026-01-23 06:02:14 +00:00
merged from trunk
[SVN r45503]
This commit is contained in:
@@ -631,6 +631,264 @@ namespace boost
|
||||
typedef typename base::bool_type bool_type;
|
||||
using base::operator bool_type;
|
||||
};
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
unsigned try_lock_internal(MutexType1& m1,MutexType2& m2)
|
||||
{
|
||||
boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
|
||||
if(!l1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if(!m2.try_lock())
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
l1.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3>
|
||||
unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3)
|
||||
{
|
||||
boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
|
||||
if(!l1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if(unsigned const failed_lock=try_lock_internal(m2,m3))
|
||||
{
|
||||
return failed_lock+1;
|
||||
}
|
||||
l1.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3,
|
||||
typename MutexType4>
|
||||
unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3,
|
||||
MutexType4& m4)
|
||||
{
|
||||
boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
|
||||
if(!l1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if(unsigned const failed_lock=try_lock_internal(m2,m3,m4))
|
||||
{
|
||||
return failed_lock+1;
|
||||
}
|
||||
l1.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3,
|
||||
typename MutexType4,typename MutexType5>
|
||||
unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3,
|
||||
MutexType4& m4,MutexType5& m5)
|
||||
{
|
||||
boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
|
||||
if(!l1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
|
||||
{
|
||||
return failed_lock+1;
|
||||
}
|
||||
l1.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
unsigned lock_helper(MutexType1& m1,MutexType2& m2)
|
||||
{
|
||||
boost::unique_lock<MutexType1> l1(m1);
|
||||
if(!m2.try_lock())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
l1.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3>
|
||||
unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3)
|
||||
{
|
||||
boost::unique_lock<MutexType1> l1(m1);
|
||||
if(unsigned const failed_lock=try_lock_internal(m2,m3))
|
||||
{
|
||||
return failed_lock;
|
||||
}
|
||||
l1.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3,
|
||||
typename MutexType4>
|
||||
unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3,
|
||||
MutexType4& m4)
|
||||
{
|
||||
boost::unique_lock<MutexType1> l1(m1);
|
||||
if(unsigned const failed_lock=try_lock_internal(m2,m3,m4))
|
||||
{
|
||||
return failed_lock;
|
||||
}
|
||||
l1.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3,
|
||||
typename MutexType4,typename MutexType5>
|
||||
unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3,
|
||||
MutexType4& m4,MutexType5& m5)
|
||||
{
|
||||
boost::unique_lock<MutexType1> l1(m1);
|
||||
if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
|
||||
{
|
||||
return failed_lock;
|
||||
}
|
||||
l1.release();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
void lock(MutexType1& m1,MutexType2& m2)
|
||||
{
|
||||
unsigned const lock_count=2;
|
||||
unsigned lock_first=0;
|
||||
while(true)
|
||||
{
|
||||
switch(lock_first)
|
||||
{
|
||||
case 0:
|
||||
lock_first=detail::lock_helper(m1,m2);
|
||||
if(!lock_first)
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
lock_first=detail::lock_helper(m2,m1);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+1)%lock_count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3>
|
||||
void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3)
|
||||
{
|
||||
unsigned const lock_count=3;
|
||||
unsigned lock_first=0;
|
||||
while(true)
|
||||
{
|
||||
switch(lock_first)
|
||||
{
|
||||
case 0:
|
||||
lock_first=detail::lock_helper(m1,m2,m3);
|
||||
if(!lock_first)
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
lock_first=detail::lock_helper(m2,m3,m1);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+1)%lock_count;
|
||||
break;
|
||||
case 2:
|
||||
lock_first=detail::lock_helper(m3,m1,m2);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+2)%lock_count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3,
|
||||
typename MutexType4>
|
||||
void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,
|
||||
MutexType4& m4)
|
||||
{
|
||||
unsigned const lock_count=4;
|
||||
unsigned lock_first=0;
|
||||
while(true)
|
||||
{
|
||||
switch(lock_first)
|
||||
{
|
||||
case 0:
|
||||
lock_first=detail::lock_helper(m1,m2,m3,m4);
|
||||
if(!lock_first)
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
lock_first=detail::lock_helper(m2,m3,m4,m1);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+1)%lock_count;
|
||||
break;
|
||||
case 2:
|
||||
lock_first=detail::lock_helper(m3,m4,m1,m2);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+2)%lock_count;
|
||||
break;
|
||||
case 3:
|
||||
lock_first=detail::lock_helper(m4,m1,m2,m3);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+3)%lock_count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3,
|
||||
typename MutexType4,typename MutexType5>
|
||||
void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,
|
||||
MutexType4& m4,MutexType5& m5)
|
||||
{
|
||||
unsigned const lock_count=5;
|
||||
unsigned lock_first=0;
|
||||
while(true)
|
||||
{
|
||||
switch(lock_first)
|
||||
{
|
||||
case 0:
|
||||
lock_first=detail::lock_helper(m1,m2,m3,m4,m5);
|
||||
if(!lock_first)
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
lock_first=detail::lock_helper(m2,m3,m4,m5,m1);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+1)%lock_count;
|
||||
break;
|
||||
case 2:
|
||||
lock_first=detail::lock_helper(m3,m4,m5,m1,m2);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+2)%lock_count;
|
||||
break;
|
||||
case 3:
|
||||
lock_first=detail::lock_helper(m4,m5,m1,m2,m3);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+3)%lock_count;
|
||||
break;
|
||||
case 4:
|
||||
lock_first=detail::lock_helper(m5,m1,m2,m3,m4);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+4)%lock_count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -174,13 +174,18 @@ namespace boost
|
||||
{
|
||||
F f;
|
||||
|
||||
#ifdef BOOST_HAS_RVALUE_REFS
|
||||
thread_data(F&& f_):
|
||||
f(static_cast<F&&>(f_))
|
||||
{}
|
||||
#else
|
||||
thread_data(F f_):
|
||||
f(f_)
|
||||
{}
|
||||
thread_data(detail::thread_move_t<F> f_):
|
||||
f(f_)
|
||||
{}
|
||||
|
||||
#endif
|
||||
void run()
|
||||
{
|
||||
f();
|
||||
@@ -201,27 +206,50 @@ namespace boost
|
||||
|
||||
detail::thread_data_ptr get_thread_info() const;
|
||||
|
||||
#ifdef BOOST_HAS_RVALUE_REFS
|
||||
template<typename F>
|
||||
static inline detail::thread_data_ptr make_thread_info(F&& f)
|
||||
{
|
||||
return detail::heap_new<thread_data<F> >(static_cast<F&&>(f));
|
||||
}
|
||||
#else
|
||||
template<typename F>
|
||||
static inline detail::thread_data_ptr make_thread_info(F f)
|
||||
{
|
||||
return detail::heap_new<thread_data<F> >(f);
|
||||
}
|
||||
template<typename F>
|
||||
static inline detail::thread_data_ptr make_thread_info(boost::detail::thread_move_t<F> f)
|
||||
{
|
||||
return detail::heap_new<thread_data<F> >(f);
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
thread();
|
||||
~thread();
|
||||
|
||||
#ifdef BOOST_HAS_RVALUE_REFS
|
||||
template <class F>
|
||||
thread(F&& f):
|
||||
thread_info(make_thread_info(static_cast<F&&>(f)))
|
||||
{
|
||||
start_thread();
|
||||
}
|
||||
#else
|
||||
template <class F>
|
||||
explicit thread(F f):
|
||||
thread_info(make_thread_info(f))
|
||||
{
|
||||
start_thread();
|
||||
}
|
||||
|
||||
template <class F>
|
||||
thread(detail::thread_move_t<F> f):
|
||||
thread_info(make_thread_info(f))
|
||||
{
|
||||
start_thread();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class F,class A1>
|
||||
thread(F f,A1 a1):
|
||||
|
||||
@@ -84,6 +84,23 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_HAS_RVALUE_REFS
|
||||
template<typename T,typename A1>
|
||||
T* heap_new(A1&& a1)
|
||||
{
|
||||
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
|
||||
try
|
||||
{
|
||||
T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
|
||||
return data;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
free_raw_heap_memory(heap_memory);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#else
|
||||
template<typename T,typename A1>
|
||||
T* heap_new(A1 a1)
|
||||
{
|
||||
@@ -99,7 +116,7 @@ namespace boost
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
template<typename T,typename A1,typename A2>
|
||||
T* heap_new(A1 a1,A2 a2)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user