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

merged from trunk

[SVN r47983]
This commit is contained in:
Eric Niebler
2008-08-05 05:39:57 +00:00
parent 6d20beb083
commit cef8fb0bd7
33 changed files with 1512 additions and 321 deletions

View File

@@ -6,8 +6,10 @@
#ifndef BOOST_THREAD_MOVE_HPP
#define BOOST_THREAD_MOVE_HPP
#ifndef BOOST_NO_SFINAE
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_convertible.hpp>
#endif
#include <boost/config/abi_prefix.hpp>
@@ -37,11 +39,13 @@ namespace boost
};
}
#ifndef BOOST_NO_SFINAE
template<typename T>
typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, detail::thread_move_t<T> >::type move(T& t)
{
return t;
}
#endif
template<typename T>
detail::thread_move_t<T> move(detail::thread_move_t<T> t)

View File

@@ -42,9 +42,9 @@
#elif defined(__QNXNTO__)
# define BOOST_THREAD_QNXNTO
#elif defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
# if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_THREAD_POSIX)
# define BOOST_THREAD_POSIX
# endif
# if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_THREAD_POSIX)
# define BOOST_THREAD_POSIX
# endif
#endif
// For every supported platform add a new entry into the dispatch table below.

View File

@@ -172,6 +172,14 @@ namespace boost
return static_cast<thread&&>(*this);
}
#else
#ifdef BOOST_NO_SFINAE
template <class F>
explicit thread(F f):
thread_info(make_thread_info(f))
{
start_thread();
}
#else
template <class F>
explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0):
@@ -179,9 +187,10 @@ namespace boost
{
start_thread();
}
#endif
template <class F>
thread(detail::thread_move_t<F> f):
explicit thread(detail::thread_move_t<F> f):
thread_info(make_thread_info(f))
{
start_thread();

View File

@@ -10,12 +10,21 @@
#include <algorithm>
#include <iterator>
#include <boost/thread/thread_time.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/abi_prefix.hpp>
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<typename T>
@@ -77,7 +86,13 @@ namespace boost
detail::has_member_try_lock<T>::value);
};
#else
template<typename T>
struct is_mutex_type
{
BOOST_STATIC_CONSTANT(bool, value = false);
};
#endif
struct defer_lock_t
{};
@@ -96,6 +111,74 @@ namespace boost
template<typename Mutex>
class upgrade_lock;
template<typename Mutex>
class unique_lock;
namespace detail
{
template<typename Mutex>
class try_lock_wrapper;
}
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
template<typename T>
struct is_mutex_type<unique_lock<T> >
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<typename T>
struct is_mutex_type<shared_lock<T> >
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<typename T>
struct is_mutex_type<upgrade_lock<T> >
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<typename T>
struct is_mutex_type<detail::try_lock_wrapper<T> >
{
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<mutex>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<>
struct is_mutex_type<timed_mutex>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<>
struct is_mutex_type<recursive_mutex>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<>
struct is_mutex_type<recursive_timed_mutex>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<>
struct is_mutex_type<shared_mutex>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
#endif
template<typename Mutex>
class lock_guard
{
@@ -126,8 +209,10 @@ namespace boost
private:
Mutex* m;
bool is_locked;
explicit unique_lock(unique_lock&);
unique_lock(unique_lock&);
explicit unique_lock(upgrade_lock<Mutex>&);
unique_lock& operator=(unique_lock&);
unique_lock& operator=(upgrade_lock<Mutex>& other);
public:
unique_lock():
m(0),is_locked(false)
@@ -154,6 +239,40 @@ namespace boost
{
timed_lock(target_time);
}
#ifdef BOOST_HAS_RVALUE_REFS
unique_lock(unique_lock&& other):
m(other.m),is_locked(other.is_locked)
{
other.is_locked=false;
other.m=0;
}
explicit unique_lock(upgrade_lock<Mutex>&& other);
unique_lock<Mutex>&& move()
{
return static_cast<unique_lock<Mutex>&&>(*this);
}
unique_lock& operator=(unique_lock<Mutex>&& other)
{
unique_lock temp(other);
swap(temp);
return *this;
}
unique_lock& operator=(upgrade_lock<Mutex>&& other)
{
unique_lock temp(other);
swap(temp);
return *this;
}
void swap(unique_lock&& other)
{
std::swap(m,other.m);
std::swap(is_locked,other.is_locked);
}
#else
unique_lock(detail::thread_move_t<unique_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
{
@@ -185,7 +304,6 @@ namespace boost
swap(temp);
return *this;
}
void swap(unique_lock& other)
{
std::swap(m,other.m);
@@ -196,6 +314,7 @@ namespace boost
std::swap(m,other->m);
std::swap(is_locked,other->is_locked);
}
#endif
~unique_lock()
{
@@ -234,6 +353,11 @@ namespace boost
is_locked=m->timed_lock(absolute_time);
return is_locked;
}
bool timed_lock(::boost::xtime const& absolute_time)
{
is_locked=m->timed_lock(absolute_time);
return is_locked;
}
void unlock()
{
if(!owns_lock())
@@ -275,11 +399,27 @@ namespace boost
friend class upgrade_lock<Mutex>;
};
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
void swap(unique_lock<Mutex>&& lhs,unique_lock<Mutex>&& rhs)
{
lhs.swap(rhs);
}
#else
template<typename Mutex>
void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs)
{
lhs.swap(rhs);
}
#endif
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
inline unique_lock<Mutex>&& move(unique_lock<Mutex>&& ul)
{
return ul;
}
#endif
template<typename Mutex>
class shared_lock
@@ -378,11 +518,29 @@ namespace boost
return *this;
}
#ifdef BOOST_HAS_RVALUE_REFS
void swap(shared_lock&& other)
{
std::swap(m,other.m);
std::swap(is_locked,other.is_locked);
}
#else
void swap(shared_lock& other)
{
std::swap(m,other.m);
std::swap(is_locked,other.is_locked);
}
void swap(boost::detail::thread_move_t<shared_lock<Mutex> > other)
{
std::swap(m,other->m);
std::swap(is_locked,other->is_locked);
}
#endif
Mutex* mutex() const
{
return m;
}
~shared_lock()
{
@@ -418,6 +576,16 @@ namespace boost
is_locked=m->timed_lock_shared(target_time);
return is_locked;
}
template<typename Duration>
bool timed_lock(Duration const& target_time)
{
if(owns_lock())
{
throw boost::lock_error();
}
is_locked=m->timed_lock_shared(target_time);
return is_locked;
}
void unlock()
{
if(!owns_lock())
@@ -428,7 +596,7 @@ namespace boost
is_locked=false;
}
typedef void (shared_lock::*bool_type)();
typedef void (shared_lock<Mutex>::*bool_type)();
operator bool_type() const
{
return is_locked?&shared_lock::lock:0;
@@ -444,6 +612,20 @@ namespace boost
};
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
void swap(shared_lock<Mutex>&& lhs,shared_lock<Mutex>&& rhs)
{
lhs.swap(rhs);
}
#else
template<typename Mutex>
void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs)
{
lhs.swap(rhs);
}
#endif
template<typename Mutex>
class upgrade_lock
{
@@ -576,6 +758,18 @@ namespace boost
};
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
unique_lock<Mutex>::unique_lock(upgrade_lock<Mutex>&& other):
m(other.m),is_locked(other.is_locked)
{
other.is_locked=false;
if(is_locked)
{
m.unlock_upgrade_and_lock();
}
}
#else
template<typename Mutex>
unique_lock<Mutex>::unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
@@ -586,7 +780,7 @@ namespace boost
m->unlock_upgrade_and_lock();
}
}
#endif
template <class Mutex>
class upgrade_to_unique_lock
{
@@ -685,6 +879,12 @@ namespace boost
return *this;
}
#ifdef BOOST_HAS_RVALUE_REFS
void swap(try_lock_wrapper&& other)
{
base::swap(other);
}
#else
void swap(try_lock_wrapper& other)
{
base::swap(other);
@@ -693,6 +893,7 @@ namespace boost
{
base::swap(*other);
}
#endif
void lock()
{
@@ -726,15 +927,23 @@ namespace boost
typedef typename base::bool_type bool_type;
operator bool_type() const
{
return static_cast<base const&>(*this);
return base::operator bool_type();
}
};
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
void swap(try_lock_wrapper<Mutex>&& lhs,try_lock_wrapper<Mutex>&& rhs)
{
lhs.swap(rhs);
}
#else
template<typename Mutex>
void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)
{
lhs.swap(rhs);
}
#endif
template<typename MutexType1,typename MutexType2>
unsigned try_lock_internal(MutexType1& m1,MutexType2& m2)
@@ -859,28 +1068,63 @@ namespace boost
}
}
template<typename MutexType1,typename MutexType2>
typename enable_if<is_mutex_type<MutexType1>, void>::type lock(MutexType1& m1,MutexType2& m2)
namespace detail
{
unsigned const lock_count=2;
unsigned lock_first=0;
while(true)
template<bool x>
struct is_mutex_type_wrapper
{};
template<typename MutexType1,typename MutexType2>
void lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper<true>)
{
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<typename Iterator>
void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>);
}
template<typename MutexType1,typename MutexType2>
void lock(MutexType1& m1,MutexType2& m2)
{
detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
}
template<typename MutexType1,typename MutexType2>
void lock(const MutexType1& m1,MutexType2& m2)
{
detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
}
template<typename MutexType1,typename MutexType2>
void lock(MutexType1& m1,const MutexType2& m2)
{
detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
}
template<typename MutexType1,typename MutexType2>
void lock(const MutexType1& m1,const MutexType2& m2)
{
detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
}
template<typename MutexType1,typename MutexType2,typename MutexType3>
@@ -995,10 +1239,52 @@ namespace boost
}
}
template<typename MutexType1,typename MutexType2>
typename enable_if<is_mutex_type<MutexType1>, int>::type try_lock(MutexType1& m1,MutexType2& m2)
namespace detail
{
return ((int)detail::try_lock_internal(m1,m2))-1;
template<typename Mutex,bool x=is_mutex_type<Mutex>::value>
struct try_lock_impl_return
{
typedef int type;
};
template<typename Iterator>
struct try_lock_impl_return<Iterator,false>
{
typedef Iterator type;
};
template<typename MutexType1,typename MutexType2>
int try_lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper<true>)
{
return ((int)detail::try_lock_internal(m1,m2))-1;
}
template<typename Iterator>
Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>);
}
template<typename MutexType1,typename MutexType2>
typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1,MutexType2& m2)
{
return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
}
template<typename MutexType1,typename MutexType2>
typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1,MutexType2& m2)
{
return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
}
template<typename MutexType1,typename MutexType2>
typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1,const MutexType2& m2)
{
return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
}
template<typename MutexType1,typename MutexType2>
typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1,const MutexType2& m2)
{
return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
}
template<typename MutexType1,typename MutexType2,typename MutexType3>
@@ -1020,9 +1306,6 @@ namespace boost
}
template<typename Iterator>
typename disable_if<is_mutex_type<Iterator>, void>::type lock(Iterator begin,Iterator end);
namespace detail
{
template<typename Iterator>
@@ -1050,70 +1333,59 @@ namespace boost
}
}
};
}
template<typename Iterator>
typename disable_if<is_mutex_type<Iterator>, Iterator>::type try_lock(Iterator begin,Iterator end)
{
if(begin==end)
{
return end;
}
typedef typename std::iterator_traits<Iterator>::value_type lock_type;
unique_lock<lock_type> 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<typename Iterator>
Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>)
template<typename Iterator>
typename disable_if<is_mutex_type<Iterator>, void>::type lock(Iterator begin,Iterator end)
{
typedef typename std::iterator_traits<Iterator>::value_type lock_type;
if(begin==end)
{
return;
}
bool start_with_begin=true;
Iterator second=begin;
++second;
Iterator next=second;
for(;;)
{
unique_lock<lock_type> 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<Iterator>::value_type lock_type;
unique_lock<lock_type> guard(*begin,try_to_lock);
if(!guard.owns_lock())
{
detail::range_lock_guard<Iterator> 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<typename Iterator>
void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>)
{
typedef typename std::iterator_traits<Iterator>::value_type lock_type;
if(begin==end)
{
return;
}
bool start_with_begin=true;
Iterator second=begin;
++second;
Iterator next=second;
for(;;)
{
unique_lock<lock_type> 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;
@@ -1121,11 +1393,28 @@ namespace boost
}
else
{
start_with_begin=true;
next=second;
detail::range_lock_guard<Iterator> 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;
}
}
}
}
}
}

View File

@@ -121,6 +121,17 @@ namespace boost
}
return true;
}
template<typename lock_type>
bool timed_wait(lock_type& m,xtime const& wait_until)
{
return timed_wait(m,system_time(wait_until));
}
template<typename lock_type,typename duration_type>
bool timed_wait(lock_type& m,duration_type const& wait_duration)
{
return timed_wait(m,get_system_time()+wait_duration);
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)

View File

@@ -47,6 +47,16 @@ namespace boost
}
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until);
bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until)
{
return timed_wait(m,system_time(wait_until));
}
template<typename duration_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
{
return timed_wait(m,get_system_time()+wait_duration);
}
template<typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)

View File

@@ -10,6 +10,7 @@
#include <boost/thread/exceptions.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/assert.hpp>
#include <errno.h>
#include "timespec.hpp"
@@ -113,6 +114,10 @@ namespace boost
{
return timed_lock(get_system_time()+relative_time);
}
bool timed_lock(boost::xtime const & absolute_time)
{
return timed_lock(system_time(absolute_time));
}
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
void lock()

View File

@@ -5,6 +5,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007-8 Anthony Williams
#include <boost/thread/detail/config.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/detail/thread_heap_alloc.hpp>

View File

@@ -13,6 +13,7 @@
#include "thread_primitives.hpp"
#include "interlocked_read.hpp"
#include <boost/thread/thread_time.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/detail/interlocked.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -117,6 +118,11 @@ namespace boost
return timed_lock(get_system_time()+timeout);
}
bool timed_lock(boost::xtime const& timeout)
{
return timed_lock(system_time(timeout));
}
long get_active_count()
{
return ::boost::detail::interlocked_read_acquire(&active_count);

View File

@@ -20,7 +20,7 @@ namespace boost
}
class mutex:
boost::noncopyable,
boost::noncopyable,
public ::boost::detail::underlying_mutex
{
public:

View File

@@ -91,7 +91,7 @@ namespace boost
bool try_lock_shared()
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
@@ -106,14 +106,6 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
}
@@ -130,17 +122,10 @@ namespace boost
bool timed_lock_shared(boost::system_time const& wait_until)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true)
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
for(;;)
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
@@ -159,14 +144,6 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
@@ -176,7 +153,7 @@ namespace boost
unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until));
if(res==detail::win32::timeout)
{
do
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
@@ -198,14 +175,6 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
@@ -221,7 +190,7 @@ namespace boost
void unlock_shared()
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
bool const last_reader=!--new_state.shared_count;
@@ -262,14 +231,6 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
void lock()
@@ -283,20 +244,39 @@ namespace boost
return timed_lock(get_system_time()+relative_time);
}
bool try_lock()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
return false;
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
return true;
}
bool timed_lock(boost::system_time const& wait_until)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true)
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
for(;;)
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
@@ -316,14 +296,6 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
if(!old_state.shared_count && !old_state.exclusive)
{
@@ -332,7 +304,7 @@ namespace boost
unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,true,::boost::detail::get_milliseconds_until(wait_until));
if(wait_res==detail::win32::timeout)
{
do
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
@@ -357,14 +329,6 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
if(!old_state.shared_count && !old_state.exclusive)
{
return true;
@@ -378,7 +342,7 @@ namespace boost
void unlock()
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
new_state.exclusive=false;
@@ -396,30 +360,15 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
release_waiters(old_state);
}
void lock_upgrade()
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true)
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
for(;;)
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
@@ -439,14 +388,6 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade))
{
@@ -457,10 +398,36 @@ namespace boost
}
}
bool try_lock_upgrade()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
{
return false;
}
else
{
++new_state.shared_count;
new_state.upgrade=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
return true;
}
void unlock_upgrade()
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
new_state.upgrade=false;
@@ -487,20 +454,12 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
void unlock_upgrade_and_lock()
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
bool const last_reader=!--new_state.shared_count;
@@ -522,20 +481,12 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
void unlock_and_lock_upgrade()
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
new_state.exclusive=false;
@@ -555,21 +506,13 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
release_waiters(old_state);
}
void unlock_and_lock_shared()
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
new_state.exclusive=false;
@@ -588,21 +531,13 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
release_waiters(old_state);
}
void unlock_upgrade_and_lock_shared()
{
state_data old_state=state;
do
for(;;)
{
state_data new_state=old_state;
new_state.upgrade=false;
@@ -620,14 +555,6 @@ namespace boost
}
old_state=current_state;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
while(true);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
release_waiters(old_state);
}

View File

@@ -64,7 +64,7 @@ namespace boost
# ifdef UNDER_CE
# ifndef WINAPI
# ifndef _WIN32_WCE_EMULATION
# define WINAPI __cdecl // Note this doesn't match the desktop definition
# define WINAPI __cdecl // Note this doesn't match the desktop definition
# else
# define WINAPI __stdcall
# endif
@@ -282,16 +282,6 @@ namespace boost
}
#if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE)
#if _MSC_VER==1400
extern "C" unsigned char _interlockedbittestandset(long *a,long b);
extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
#else
extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
#endif
#pragma intrinsic(_interlockedbittestandset)
#pragma intrinsic(_interlockedbittestandreset)
namespace boost
{
@@ -299,6 +289,17 @@ namespace boost
{
namespace win32
{
#if _MSC_VER==1400
extern "C" unsigned char _interlockedbittestandset(long *a,long b);
extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
#else
extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
#endif
#pragma intrinsic(_interlockedbittestandset)
#pragma intrinsic(_interlockedbittestandreset)
inline bool interlocked_bit_test_and_set(long* x,long bit)
{
return _interlockedbittestandset(x,bit)!=0;