diff --git a/include/boost/thread/detail/move.hpp b/include/boost/thread/detail/move.hpp index f8917758..91b2eda1 100644 --- a/include/boost/thread/detail/move.hpp +++ b/include/boost/thread/detail/move.hpp @@ -6,8 +6,10 @@ #ifndef BOOST_THREAD_MOVE_HPP #define BOOST_THREAD_MOVE_HPP +#ifndef BOOST_NO_SFINAE #include #include +#endif #include @@ -37,11 +39,13 @@ namespace boost }; } +#ifndef BOOST_NO_SFINAE template typename enable_if >, detail::thread_move_t >::type move(T& t) { return t; } +#endif template detail::thread_move_t move(detail::thread_move_t t) diff --git a/include/boost/thread/detail/thread.hpp b/include/boost/thread/detail/thread.hpp index a7e82f7f..3d39d1df 100644 --- a/include/boost/thread/detail/thread.hpp +++ b/include/boost/thread/detail/thread.hpp @@ -172,6 +172,14 @@ namespace boost return static_cast(*this); } +#else +#ifdef BOOST_NO_SFINAE + template + explicit thread(F f): + thread_info(make_thread_info(f)) + { + start_thread(); + } #else template explicit thread(F f,typename disable_if >, dummy* >::type=0): @@ -179,9 +187,10 @@ namespace boost { start_thread(); } +#endif template - thread(detail::thread_move_t f): + explicit thread(detail::thread_move_t f): thread_info(make_thread_info(f)) { start_thread(); diff --git a/include/boost/thread/locks.hpp b/include/boost/thread/locks.hpp index 66a07371..6e4341ad 100644 --- a/include/boost/thread/locks.hpp +++ b/include/boost/thread/locks.hpp @@ -10,14 +10,21 @@ #include #include #include -#include +#include #include namespace boost { struct xtime; - + +#if defined(BOOST_NO_SFINAE) || \ + BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \ + BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) +#define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES +#endif + +#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES namespace detail { template @@ -79,7 +86,13 @@ namespace boost detail::has_member_try_lock::value); }; - +#else + template + struct is_mutex_type + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; +#endif struct defer_lock_t {}; @@ -98,6 +111,74 @@ namespace boost template class upgrade_lock; + template + class unique_lock; + + namespace detail + { + template + class try_lock_wrapper; + } + +#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES + template + struct is_mutex_type > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template + struct is_mutex_type > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template + struct is_mutex_type > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template + struct is_mutex_type > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + class mutex; + class timed_mutex; + class recursive_mutex; + class recursive_timed_mutex; + class shared_mutex; + + template<> + struct is_mutex_type + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + template<> + struct is_mutex_type + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + template<> + struct is_mutex_type + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + template<> + struct is_mutex_type + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + template<> + struct is_mutex_type + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + +#endif + template class lock_guard { @@ -449,7 +530,7 @@ namespace boost std::swap(m,other.m); std::swap(is_locked,other.is_locked); } - void swap(boost::detail::thread_move_t other) + void swap(boost::detail::thread_move_t > other) { std::swap(m,other->m); std::swap(is_locked,other->is_locked); @@ -515,7 +596,7 @@ namespace boost is_locked=false; } - typedef void (shared_lock::*bool_type)(); + typedef void (shared_lock::*bool_type)(); operator bool_type() const { return is_locked?&shared_lock::lock:0; @@ -846,7 +927,7 @@ namespace boost typedef typename base::bool_type bool_type; operator bool_type() const { - return static_cast(*this); + return base::operator bool_type(); } }; @@ -987,28 +1068,63 @@ namespace boost } } - template - typename enable_if, void>::type lock(MutexType1& m1,MutexType2& m2) + namespace detail { - unsigned const lock_count=2; - unsigned lock_first=0; - while(true) + template + struct is_mutex_type_wrapper + {}; + + template + void lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper) { - switch(lock_first) + unsigned const lock_count=2; + unsigned lock_first=0; + while(true) { - 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; + 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 + void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper); + } + + + template + void lock(MutexType1& m1,MutexType2& m2) + { + detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper::value>()); + } + + template + void lock(const MutexType1& m1,MutexType2& m2) + { + detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper::value>()); + } + + template + void lock(MutexType1& m1,const MutexType2& m2) + { + detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper::value>()); + } + + template + void lock(const MutexType1& m1,const MutexType2& m2) + { + detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper::value>()); } template @@ -1123,10 +1239,52 @@ namespace boost } } - template - typename enable_if, int>::type try_lock(MutexType1& m1,MutexType2& m2) + namespace detail { - return ((int)detail::try_lock_internal(m1,m2))-1; + template::value> + struct try_lock_impl_return + { + typedef int type; + }; + + template + struct try_lock_impl_return + { + typedef Iterator type; + }; + + template + int try_lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper) + { + return ((int)detail::try_lock_internal(m1,m2))-1; + } + + template + Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper); + } + + template + typename detail::try_lock_impl_return::type try_lock(MutexType1& m1,MutexType2& m2) + { + return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper::value>()); + } + + template + typename detail::try_lock_impl_return::type try_lock(const MutexType1& m1,MutexType2& m2) + { + return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper::value>()); + } + + template + typename detail::try_lock_impl_return::type try_lock(MutexType1& m1,const MutexType2& m2) + { + return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper::value>()); + } + + template + typename detail::try_lock_impl_return::type try_lock(const MutexType1& m1,const MutexType2& m2) + { + return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper::value>()); } template @@ -1148,9 +1306,6 @@ namespace boost } - template - typename disable_if, void>::type lock(Iterator begin,Iterator end); - namespace detail { template @@ -1178,70 +1333,59 @@ namespace boost } } }; - } - template - typename disable_if, Iterator>::type try_lock(Iterator begin,Iterator end) - { - if(begin==end) - { - return end; - } - typedef typename std::iterator_traits::value_type lock_type; - unique_lock guard(*begin,try_to_lock); - - if(!guard.owns_lock()) - { - return begin; - } - Iterator const failed=try_lock(++begin,end); - if(failed==end) - { - guard.release(); - } - - return failed; - } + template + Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper) - template - typename disable_if, void>::type lock(Iterator begin,Iterator end) - { - typedef typename std::iterator_traits::value_type lock_type; - - if(begin==end) { - return; - } - bool start_with_begin=true; - Iterator second=begin; - ++second; - Iterator next=second; - - for(;;) - { - unique_lock begin_lock(*begin,defer_lock); - if(start_with_begin) + if(begin==end) { - begin_lock.lock(); - Iterator const failed_lock=try_lock(next,end); - if(failed_lock==end) - { - begin_lock.release(); - return; - } - start_with_begin=false; - next=failed_lock; + return end; } - else + typedef typename std::iterator_traits::value_type lock_type; + unique_lock guard(*begin,try_to_lock); + + if(!guard.owns_lock()) { - detail::range_lock_guard guard(next,end); - if(begin_lock.try_lock()) + return begin; + } + Iterator const failed=try_lock(++begin,end); + if(failed==end) + { + guard.release(); + } + + return failed; + } + } + + + namespace detail + { + template + void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper) + { + typedef typename std::iterator_traits::value_type lock_type; + + if(begin==end) + { + return; + } + bool start_with_begin=true; + Iterator second=begin; + ++second; + Iterator next=second; + + for(;;) + { + unique_lock begin_lock(*begin,defer_lock); + if(start_with_begin) { - Iterator const failed_lock=try_lock(second,next); - if(failed_lock==next) + begin_lock.lock(); + Iterator const failed_lock=try_lock(next,end); + if(failed_lock==end) { begin_lock.release(); - guard.release(); return; } start_with_begin=false; @@ -1249,16 +1393,32 @@ namespace boost } else { - start_with_begin=true; - next=second; + detail::range_lock_guard guard(next,end); + if(begin_lock.try_lock()) + { + Iterator const failed_lock=try_lock(second,next); + if(failed_lock==next) + { + begin_lock.release(); + guard.release(); + return; + } + start_with_begin=false; + next=failed_lock; + } + else + { + start_with_begin=true; + next=second; + } } } } + } } #include -#include #endif diff --git a/src/pthread/thread.cpp b/src/pthread/thread.cpp index 2ceb68af..9e1a5146 100644 --- a/src/pthread/thread.cpp +++ b/src/pthread/thread.cpp @@ -18,7 +18,7 @@ #elif defined(__APPLE__) || defined(__FreeBSD__) #include #include -#elif defined(__sun) || defined(__CYGWIN__) +#elif defined BOOST_HAS_UNISTD_H #include #endif @@ -394,7 +394,7 @@ namespace boost int count; size_t size=sizeof(count); return sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count; -#elif defined(__sun) || defined(__CYGWIN__) +#elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN) int const count=sysconf(_SC_NPROCESSORS_ONLN); return (count>0)?count:0; #else diff --git a/test/test_generic_locks.cpp b/test/test_generic_locks.cpp index a091976e..d3880d5c 100644 --- a/test/test_generic_locks.cpp +++ b/test/test_generic_locks.cpp @@ -272,6 +272,16 @@ struct dummy_mutex } }; +namespace boost +{ + template<> + struct is_mutex_type + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; +} + + void test_lock_five_in_range() {