2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-04 09:52:14 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Beman Dawes
ddb4981ce7 Release 1.43.0
[SVN r61817]
2010-05-06 13:21:09 +00:00
34 changed files with 310 additions and 881 deletions

View File

@@ -43,7 +43,6 @@ project boost/thread
<link>shared:<define>BOOST_THREAD_BUILD_DLL=1
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).tag
<toolset>gcc:<cxxflags>-Wno-long-long
: default-build <threading>multi
;

View File

@@ -26,6 +26,11 @@ boostbook standalone
<xsl:param>generate.section.toc.level=10
# Path for links to Boost:
<xsl:param>boost.root=../../../..
# Path for libraries index:
<xsl:param>boost.libraries=../../../../libs/libraries.htm
# Use the main Boost stylesheet:
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
;

View File

@@ -219,7 +219,6 @@ __thread_id__ yield a total order for every non-equal thread ID.
};
void swap(thread& lhs,thread& rhs);
detail::thread_move_t<thread> move(detail::thread_move_t<thread> t);
[section:default_constructor Default Constructor]
@@ -235,40 +234,6 @@ __thread_id__ yield a total order for every non-equal thread ID.
[endsect]
[section:move_constructor Move Constructor]
thread(detail::thread_move_t<thread> other);
[variablelist
[[Effects:] [Transfers ownership of the thread managed by `other` (if any) to the newly constructed __thread__ instance.]]
[[Postconditions:] [`other->get_id()==thread::id()`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:move_assignment Move assignment operator]
thread& operator=(detail::thread_move_t<thread> other);
[variablelist
[[Effects:] [Transfers ownership of the thread managed by `other` (if
any) to `*this`. If there was a thread previously associated with
`*this` then that thread is detached.]]
[[Postconditions:] [`other->get_id()==thread::id()`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:callable_constructor Thread Constructor]
template<typename Callable>
@@ -556,26 +521,6 @@ value as `this->get_id()` prior to the call.]]
[endsect]
[section:non_member_move Non-member function `move()`]
#include <boost/thread/thread.hpp>
detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
[variablelist
[[Returns:] [`t`.]]
]
Enables moving thread objects. e.g.
extern void some_func();
boost::thread t(some_func);
boost::thread t2(boost::move(t)); // transfer thread from t to t2
[endsect]
[section:id Class `boost::thread::id`]
@@ -811,14 +756,11 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
{
template<typename TimeDuration>
void sleep(TimeDuration const& rel_time);
void sleep(system_time const& abs_time)
}
[variablelist
[[Effects:] [Suspends the current thread until the time period
specified by `rel_time` has elapsed or the time point specified by
`abs_time` has been reached.]]
[[Effects:] [Suspends the current thread until the specified time has elapsed.]]
[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]

View File

@@ -19,14 +19,8 @@
#include "platform.hpp"
// provided for backwards compatibility, since this
// macro was used for several releases by mistake.
#if defined(BOOST_THREAD_DYN_DLL)
# define BOOST_THREAD_DYN_LINK
#endif
// compatibility with the rest of Boost's auto-linking code:
#if defined(BOOST_THREAD_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
#if defined(BOOST_THREAD_DYN_DLL) || defined(BOOST_ALL_DYN_LINK)
# undef BOOST_THREAD_USE_LIB
# define BOOST_THREAD_USE_DLL
#endif

View File

@@ -29,7 +29,7 @@
# define BOOST_THREAD_HPUX
#elif defined(__CYGWIN__)
# define BOOST_THREAD_CYGWIN
#elif (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(BOOST_DISABLE_WIN32)
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define BOOST_THREAD_WIN32
#elif defined(__BEOS__)
# define BOOST_THREAD_BEOS

View File

@@ -3,12 +3,10 @@
// 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)
// (C) Copyright 2007-10 Anthony Williams
// (C) Copyright 2007-8 Anthony Williams
#include <boost/thread/exceptions.hpp>
#ifndef BOOST_NO_IOSTREAM
#include <ostream>
#endif
#include <boost/thread/detail/move.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/xtime.hpp>
@@ -115,13 +113,14 @@ namespace boost
void release_handle();
mutable boost::mutex thread_info_mutex;
detail::thread_data_ptr thread_info;
void start_thread();
explicit thread(detail::thread_data_ptr data);
detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const;
detail::thread_data_ptr get_thread_info() const;
#ifndef BOOST_NO_RVALUE_REFERENCES
template<typename F>
@@ -148,7 +147,7 @@ namespace boost
#endif
struct dummy;
public:
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#ifdef __SUNPRO_CC
thread(const volatile thread&);
#endif
thread();
@@ -158,7 +157,7 @@ namespace boost
#ifdef BOOST_MSVC
template <class F>
explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0):
thread_info(make_thread_info(static_cast<F&&>(f)))
thread_info(make_thread_info(f))
{
start_thread();
}
@@ -218,7 +217,7 @@ namespace boost
x->thread_info.reset();
}
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#ifdef __SUNPRO_CC
thread& operator=(thread x)
{
swap(x);
@@ -395,7 +394,7 @@ namespace boost
thread_data(thread_data_)
{}
friend class thread;
friend id BOOST_THREAD_DECL this_thread::get_id();
friend id this_thread::get_id();
public:
id():
thread_data()
@@ -431,8 +430,6 @@ namespace boost
return !(thread_data<y.thread_data);
}
#ifndef BOOST_NO_IOSTREAM
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class charT, class traits>
friend std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const id& x)
@@ -446,34 +443,8 @@ namespace boost
return os<<"{Not-any-thread}";
}
}
#else
template<class charT, class traits>
std::basic_ostream<charT, traits>&
print(std::basic_ostream<charT, traits>& os) const
{
if(thread_data)
{
return os<<thread_data;
}
else
{
return os<<"{Not-any-thread}";
}
}
#endif
#endif
};
#if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class charT, class traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const thread::id& x)
{
return x.print(os);
}
#endif
inline bool thread::operator==(const thread& other) const
{
return get_id()==other.get_id();

View File

@@ -18,13 +18,10 @@
namespace boost
{
class thread_group
class thread_group:
private noncopyable
{
private:
thread_group(thread_group const&);
thread_group& operator=(thread_group const&);
public:
thread_group() {}
~thread_group()
{
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();

View File

@@ -12,9 +12,27 @@
#if defined(BOOST_HAS_WINTHREADS)
namespace boost
{
BOOST_THREAD_DECL void __cdecl on_process_enter(void);
typedef void (__cdecl *thread_exit_handler)(void);
extern "C" BOOST_THREAD_DECL int at_thread_exit(
thread_exit_handler exit_handler
);
//Add a function to the list of functions that will
//be called when a thread is about to exit.
//Currently only implemented for Win32, but should
//later be implemented for all platforms.
//Used by Win32 implementation of Boost.Threads
//tss to perform cleanup.
//Like the C runtime library atexit() function,
//which it mimics, at_thread_exit() returns
//zero if successful and a nonzero
//value if an error occurs.
#endif //defined(BOOST_HAS_WINTHREADS)
#if defined(BOOST_HAS_WINTHREADS)
extern "C" BOOST_THREAD_DECL void on_process_enter(void);
//Function to be called when the exe or dll
//that uses Boost.Threads first starts
//or is first loaded.
@@ -24,7 +42,7 @@ namespace boost
//a method for doing so has been discovered.
//May be omitted; may be called multiple times.
BOOST_THREAD_DECL void __cdecl on_process_exit(void);
extern "C" BOOST_THREAD_DECL void on_process_exit(void);
//Function to be called when the exe or dll
//that uses Boost.Threads first starts
//or is first loaded.
@@ -34,7 +52,7 @@ namespace boost
//a method for doing so has been discovered.
//Must not be omitted; may be called multiple times.
BOOST_THREAD_DECL void __cdecl on_thread_enter(void);
extern "C" BOOST_THREAD_DECL void on_thread_enter(void);
//Function to be called just after a thread starts
//in an exe or dll that uses Boost.Threads.
//Must be called in the context of the thread
@@ -43,7 +61,7 @@ namespace boost
//a method for doing so has been discovered.
//May be omitted; may be called multiple times.
BOOST_THREAD_DECL void __cdecl on_thread_exit(void);
extern "C" BOOST_THREAD_DECL void __cdecl on_thread_exit(void);
//Function to be called just be fore a thread ends
//in an exe or dll that uses Boost.Threads.
//Must be called in the context of the thread
@@ -52,11 +70,10 @@ namespace boost
//a method for doing so has been discovered.
//Must not be omitted; may be called multiple times.
void tss_cleanup_implemented();
extern "C" void tss_cleanup_implemented(void);
//Dummy function used both to detect whether tss cleanup
//cleanup has been implemented and to force
//it to be linked into the Boost.Threads library.
}
#endif //defined(BOOST_HAS_WINTHREADS)

View File

@@ -9,8 +9,6 @@
#include <stdexcept>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
@@ -142,8 +140,6 @@ namespace boost
{
lock.lock();
}
private:
relocker& operator=(relocker const&);
};
void do_callback(boost::unique_lock<boost::mutex>& lock)
@@ -392,18 +388,15 @@ namespace boost
class future_waiter
{
struct registered_waiter;
typedef std::vector<registered_waiter>::size_type count_type;
struct registered_waiter
{
boost::shared_ptr<detail::future_object_base> future;
detail::future_object_base::waiter_list::iterator wait_iterator;
count_type index;
unsigned index;
registered_waiter(boost::shared_ptr<detail::future_object_base> const& future_,
detail::future_object_base::waiter_list::iterator wait_iterator_,
count_type index_):
unsigned index_):
future(future_),wait_iterator(wait_iterator_),index(index_)
{}
@@ -411,6 +404,7 @@ namespace boost
struct all_futures_lock
{
typedef std::vector<registered_waiter>::size_type count_type;
count_type count;
boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
@@ -430,7 +424,7 @@ namespace boost
void unlock()
{
for(count_type i=0;i<count;++i)
for(unsigned i=0;i<count;++i)
{
locks[i].unlock();
}
@@ -439,7 +433,7 @@ namespace boost
boost::condition_variable_any cv;
std::vector<registered_waiter> futures;
count_type future_count;
unsigned future_count;
public:
future_waiter():
@@ -456,12 +450,12 @@ namespace boost
++future_count;
}
count_type wait()
unsigned wait()
{
all_futures_lock lk(futures);
for(;;)
{
for(count_type i=0;i<futures.size();++i)
for(unsigned i=0;i<futures.size();++i)
{
if(futures[i].future->done)
{
@@ -474,7 +468,7 @@ namespace boost
~future_waiter()
{
for(count_type i=0;i<futures.size();++i)
for(unsigned i=0;i<futures.size();++i)
{
futures[i].future->remove_external_waiter(futures[i].wait_iterator);
}
@@ -554,9 +548,6 @@ namespace boost
template<typename Iterator>
typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
{
if(begin==end)
return end;
detail::future_waiter waiter;
for(Iterator current=begin;current!=end;++current)
{
@@ -912,10 +903,10 @@ namespace boost
void lazy_init()
{
if(!atomic_load(&future))
if(!future)
{
future_ptr blank;
atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<R>));
future_obtained=false;
future.reset(new detail::future_object<R>);
}
}
@@ -945,14 +936,12 @@ namespace boost
future_obtained(rhs.future_obtained)
{
future.swap(rhs.future);
rhs.future_obtained=false;
}
promise & operator=(promise&& rhs)
{
future.swap(rhs.future);
future_obtained=rhs.future_obtained;
rhs.future.reset();
rhs.future_obtained=false;
return *this;
}
#else
@@ -960,14 +949,12 @@ namespace boost
future(rhs->future),future_obtained(rhs->future_obtained)
{
rhs->future.reset();
rhs->future_obtained=false;
}
promise & operator=(boost::detail::thread_move_t<promise> rhs)
{
future=rhs->future;
future_obtained=rhs->future_obtained;
rhs->future.reset();
rhs->future_obtained=false;
return *this;
}
@@ -1051,10 +1038,10 @@ namespace boost
void lazy_init()
{
if(!atomic_load(&future))
if(!future)
{
future_ptr blank;
atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<void>));
future_obtained=false;
future.reset(new detail::future_object<void>);
}
}
public:
@@ -1083,14 +1070,12 @@ namespace boost
future_obtained(rhs.future_obtained)
{
future.swap(rhs.future);
rhs.future_obtained=false;
}
promise & operator=(promise&& rhs)
{
future.swap(rhs.future);
future_obtained=rhs.future_obtained;
rhs.future.reset();
rhs.future_obtained=false;
return *this;
}
#else
@@ -1098,14 +1083,12 @@ namespace boost
future(rhs->future),future_obtained(rhs->future_obtained)
{
rhs->future.reset();
rhs->future_obtained=false;
}
promise & operator=(boost::detail::thread_move_t<promise> rhs)
{
future=rhs->future;
future_obtained=rhs->future_obtained;
rhs->future.reset();
rhs->future_obtained=false;
return *this;
}

View File

@@ -11,7 +11,6 @@
#include <iterator>
#include <boost/thread/thread_time.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -28,52 +27,8 @@ namespace boost
#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
namespace detail
{
#define BOOST_DEFINE_HAS_MEMBER_CALLED(member_name) \
template<typename T, bool=boost::is_class<T>::value> \
struct has_member_called_##member_name \
{ \
BOOST_STATIC_CONSTANT(bool, value=false); \
}; \
\
template<typename T> \
struct has_member_called_##member_name<T,true> \
{ \
typedef char true_type; \
struct false_type \
{ \
true_type dummy[2]; \
}; \
\
struct fallback { int member_name; }; \
struct derived: \
T, fallback \
{ \
derived(); \
}; \
\
template<int fallback::*> struct tester; \
\
template<typename U> \
static false_type has_member(tester<&U::member_name>*); \
template<typename U> \
static true_type has_member(...); \
\
BOOST_STATIC_CONSTANT( \
bool, value=sizeof(has_member<derived>(0))==sizeof(true_type)); \
}
BOOST_DEFINE_HAS_MEMBER_CALLED(lock);
BOOST_DEFINE_HAS_MEMBER_CALLED(unlock);
BOOST_DEFINE_HAS_MEMBER_CALLED(try_lock);
template<typename T,bool=has_member_called_lock<T>::value >
template<typename T>
struct has_member_lock
{
BOOST_STATIC_CONSTANT(bool, value=false);
};
template<typename T>
struct has_member_lock<T,true>
{
typedef char true_type;
struct false_type
@@ -81,23 +36,15 @@ namespace boost
true_type dummy[2];
};
template<typename U,typename V>
static true_type has_member(V (U::*)());
template<typename U>
static false_type has_member(U);
static true_type has_member(U*,void (U::*dummy)()=&U::lock);
static false_type has_member(void*);
BOOST_STATIC_CONSTANT(
bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type));
BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_lock<T>::has_member((T*)NULL))==sizeof(true_type));
};
template<typename T,bool=has_member_called_unlock<T>::value >
template<typename T>
struct has_member_unlock
{
BOOST_STATIC_CONSTANT(bool, value=false);
};
template<typename T>
struct has_member_unlock<T,true>
{
typedef char true_type;
struct false_type
@@ -105,23 +52,15 @@ namespace boost
true_type dummy[2];
};
template<typename U,typename V>
static true_type has_member(V (U::*)());
template<typename U>
static false_type has_member(U);
static true_type has_member(U*,void (U::*dummy)()=&U::unlock);
static false_type has_member(void*);
BOOST_STATIC_CONSTANT(
bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type));
BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_unlock<T>::has_member((T*)NULL))==sizeof(true_type));
};
template<typename T,bool=has_member_called_try_lock<T>::value >
template<typename T>
struct has_member_try_lock
{
BOOST_STATIC_CONSTANT(bool, value=false);
};
template<typename T>
struct has_member_try_lock<T,true>
{
typedef char true_type;
struct false_type
@@ -130,12 +69,10 @@ namespace boost
};
template<typename U>
static true_type has_member(bool (U::*)());
template<typename U>
static false_type has_member(U);
static true_type has_member(U*,bool (U::*dummy)()=&U::try_lock);
static false_type has_member(void*);
BOOST_STATIC_CONSTANT(
bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type));
BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_try_lock<T>::has_member((T*)NULL))==sizeof(true_type));
};
}
@@ -277,7 +214,7 @@ namespace boost
unique_lock& operator=(unique_lock&);
unique_lock& operator=(upgrade_lock<Mutex>& other);
public:
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#ifdef __SUNPRO_CC
unique_lock(const volatile unique_lock&);
#endif
unique_lock():
@@ -363,7 +300,7 @@ namespace boost
return detail::thread_move_t<unique_lock<Mutex> >(*this);
}
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#ifdef __SUNPRO_CC
unique_lock& operator=(unique_lock<Mutex> other)
{
swap(other);
@@ -485,18 +422,6 @@ namespace boost
{
lhs.swap(rhs);
}
template<typename Mutex>
inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>&& ul)
{
return static_cast<upgrade_lock<Mutex>&&>(ul);
}
template<typename Mutex>
inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>& ul)
{
return static_cast<upgrade_lock<Mutex>&&>(ul);
}
#endif
template<typename Mutex>
void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs)
@@ -753,39 +678,6 @@ namespace boost
{
try_lock();
}
#ifdef BOOST_HAS_RVALUE_REFS
upgrade_lock(upgrade_lock<Mutex>&& other):
m(other.m),is_locked(other.is_locked)
{
other.is_locked=false;
other.m=0;
}
upgrade_lock(unique_lock<Mutex>&& other):
m(other.m),is_locked(other.is_locked)
{
if(is_locked)
{
m->unlock_and_lock_upgrade();
}
other.is_locked=false;
other.m=0;
}
upgrade_lock& operator=(upgrade_lock<Mutex>&& other)
{
upgrade_lock temp(static_cast<upgrade_lock<Mutex>&&>(other));
swap(temp);
return *this;
}
upgrade_lock& operator=(unique_lock<Mutex>&& other)
{
upgrade_lock temp(static_cast<unique_lock<Mutex>&&>(other));
swap(temp);
return *this;
}
#else
upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
{
@@ -828,7 +720,6 @@ namespace boost
swap(temp);
return *this;
}
#endif
void swap(upgrade_lock& other)
{
@@ -933,20 +824,6 @@ namespace boost
}
}
#ifdef BOOST_HAS_RVALUE_REFS
upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other):
source(other.source),exclusive(move(other.exclusive))
{
other.source=0;
}
upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Mutex>&& other)
{
upgrade_to_unique_lock temp(other);
swap(temp);
return *this;
}
#else
upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other):
source(other->source),exclusive(move(other->exclusive))
{
@@ -959,7 +836,6 @@ namespace boost
swap(temp);
return *this;
}
#endif
void swap(upgrade_to_unique_lock& other)
{
std::swap(source,other.source);
@@ -1047,15 +923,15 @@ namespace boost
return *this;
}
void swap(try_lock_wrapper& other)
{
base::swap(other);
}
void swap(detail::thread_move_t<try_lock_wrapper<Mutex> > other)
{
base::swap(*other);
}
#endif
void swap(try_lock_wrapper& other)
{
base::swap(other);
}
void lock()
{
base::lock();
@@ -1240,7 +1116,7 @@ namespace boost
{
unsigned const lock_count=2;
unsigned lock_first=0;
for(;;)
while(true)
{
switch(lock_first)
{
@@ -1293,7 +1169,7 @@ namespace boost
{
unsigned const lock_count=3;
unsigned lock_first=0;
for(;;)
while(true)
{
switch(lock_first)
{
@@ -1325,7 +1201,7 @@ namespace boost
{
unsigned const lock_count=4;
unsigned lock_first=0;
for(;;)
while(true)
{
switch(lock_first)
{
@@ -1363,7 +1239,7 @@ namespace boost
{
unsigned const lock_count=5;
unsigned lock_first=0;
for(;;)
while(true)
{
switch(lock_first)
{

View File

@@ -3,7 +3,7 @@
// 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)
// (C) Copyright 2007-10 Anthony Williams
// (C) Copyright 2007-8 Anthony Williams
#include "timespec.hpp"
#include "pthread_mutex_scoped_lock.hpp"
@@ -14,55 +14,17 @@
namespace boost
{
namespace this_thread
{
void BOOST_THREAD_DECL interruption_point();
}
namespace thread_cv_detail
{
template<typename MutexType>
struct lock_on_exit
{
MutexType* m;
lock_on_exit():
m(0)
{}
void activate(MutexType& m_)
{
m_.unlock();
m=&m_;
}
~lock_on_exit()
{
if(m)
{
m->lock();
}
}
};
}
inline void condition_variable::wait(unique_lock<mutex>& m)
{
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
int const res=pthread_cond_wait(&cond,&internal_mutex);
BOOST_ASSERT(!res);
this_thread::interruption_point();
detail::interruption_checker check_for_interruption(&cond);
BOOST_VERIFY(!pthread_cond_wait(&cond,m.mutex()->native_handle()));
}
inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
{
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
detail::interruption_checker check_for_interruption(&cond);
struct timespec const timeout=detail::get_timespec(wait_until);
int const cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
this_thread::interruption_point();
int const cond_res=pthread_cond_timedwait(&cond,m.mutex()->native_handle(),&timeout);
if(cond_res==ETIMEDOUT)
{
return false;
@@ -73,13 +35,11 @@ namespace boost
inline void condition_variable::notify_one()
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
BOOST_VERIFY(!pthread_cond_signal(&cond));
}
inline void condition_variable::notify_all()
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
BOOST_VERIFY(!pthread_cond_broadcast(&cond));
}
@@ -88,8 +48,8 @@ namespace boost
pthread_mutex_t internal_mutex;
pthread_cond_t cond;
condition_variable_any(condition_variable_any&);
condition_variable_any& operator=(condition_variable_any&);
condition_variable_any(condition_variable&);
condition_variable_any& operator=(condition_variable&);
public:
condition_variable_any()
@@ -117,11 +77,13 @@ namespace boost
{
int res=0;
{
thread_cv_detail::lock_on_exit<lock_type> guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
res=pthread_cond_wait(&cond,&internal_mutex);
this_thread::interruption_point();
detail::interruption_checker check_for_interruption(&cond);
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
m.unlock();
res=pthread_cond_wait(&cond,&internal_mutex);
}
m.lock();
}
if(res)
{
@@ -141,11 +103,13 @@ namespace boost
struct timespec const timeout=detail::get_timespec(wait_until);
int res=0;
{
thread_cv_detail::lock_on_exit<lock_type> guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
this_thread::interruption_point();
detail::interruption_checker check_for_interruption(&cond);
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
m.unlock();
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
}
m.lock();
}
if(res==ETIMEDOUT)
{

View File

@@ -20,7 +20,6 @@ namespace boost
class condition_variable
{
private:
pthread_mutex_t internal_mutex;
pthread_cond_t cond;
condition_variable(condition_variable&);
@@ -29,21 +28,14 @@ namespace boost
public:
condition_variable()
{
int const res=pthread_mutex_init(&internal_mutex,NULL);
int const res=pthread_cond_init(&cond,NULL);
if(res)
{
boost::throw_exception(thread_resource_error());
}
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
boost::throw_exception(thread_resource_error());
}
}
~condition_variable()
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
BOOST_VERIFY(!pthread_cond_destroy(&cond));
}
@@ -55,8 +47,7 @@ namespace boost
while(!pred()) wait(m);
}
inline bool timed_wait(unique_lock<mutex>& m,
boost::system_time const& wait_until);
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));

View File

@@ -27,11 +27,10 @@
namespace boost
{
class mutex
class mutex:
boost::noncopyable
{
private:
mutex(mutex const&);
mutex& operator=(mutex const&);
pthread_mutex_t m;
public:
mutex()
@@ -49,11 +48,7 @@ namespace boost
void lock()
{
int const res=pthread_mutex_lock(&m);
if(res)
{
boost::throw_exception(lock_error(res));
}
BOOST_VERIFY(!pthread_mutex_lock(&m));
}
void unlock()
@@ -64,11 +59,7 @@ namespace boost
bool try_lock()
{
int const res=pthread_mutex_trylock(&m);
if(res && (res!=EBUSY))
{
boost::throw_exception(lock_error(res));
}
BOOST_ASSERT(!res || res==EBUSY);
return !res;
}
@@ -84,11 +75,9 @@ namespace boost
typedef mutex try_mutex;
class timed_mutex
class timed_mutex:
boost::noncopyable
{
private:
timed_mutex(timed_mutex const&);
timed_mutex& operator=(timed_mutex const&);
private:
pthread_mutex_t m;
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK

View File

@@ -18,25 +18,15 @@ namespace boost
class pthread_mutex_scoped_lock
{
pthread_mutex_t* m;
bool locked;
public:
explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_):
m(m_),locked(true)
m(m_)
{
BOOST_VERIFY(!pthread_mutex_lock(m));
}
void unlock()
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
locked=false;
}
~pthread_mutex_scoped_lock()
{
if(locked)
{
unlock();
}
BOOST_VERIFY(!pthread_mutex_unlock(m));
}
};

View File

@@ -26,30 +26,18 @@
#endif
#endif
#if defined(BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK)
#define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#endif
#include <boost/config/abi_prefix.hpp>
namespace boost
{
class recursive_mutex
class recursive_mutex:
boost::noncopyable
{
private:
recursive_mutex(recursive_mutex const&);
recursive_mutex& operator=(recursive_mutex const&);
pthread_mutex_t m;
#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
pthread_cond_t cond;
bool is_locked;
pthread_t owner;
unsigned count;
#endif
public:
recursive_mutex()
{
#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
pthread_mutexattr_t attr;
int const init_attr_res=pthread_mutexattr_init(&attr);
@@ -60,42 +48,21 @@ namespace boost
int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
if(set_attr_res)
{
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
boost::throw_exception(thread_resource_error());
}
int const res=pthread_mutex_init(&m,&attr);
if(res)
{
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
boost::throw_exception(thread_resource_error());
}
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
#else
int const res=pthread_mutex_init(&m,NULL);
if(res)
{
boost::throw_exception(thread_resource_error());
}
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error());
}
is_locked=false;
count=0;
#endif
}
~recursive_mutex()
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
BOOST_VERIFY(!pthread_cond_destroy(&cond));
#endif
}
#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
void lock()
{
BOOST_VERIFY(!pthread_mutex_lock(&m));
@@ -112,70 +79,25 @@ namespace boost
BOOST_ASSERT(!res || res==EBUSY);
return !res;
}
typedef pthread_mutex_t* native_handle_type;
native_handle_type native_handle()
{
return &m;
}
#else
void lock()
{
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
if(is_locked && pthread_equal(owner,pthread_self()))
{
++count;
return;
}
while(is_locked)
{
BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
}
is_locked=true;
++count;
owner=pthread_self();
}
void unlock()
{
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
if(!--count)
{
is_locked=false;
}
BOOST_VERIFY(!pthread_cond_signal(&cond));
}
bool try_lock()
{
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
if(is_locked && !pthread_equal(owner,pthread_self()))
{
return false;
}
is_locked=true;
++count;
owner=pthread_self();
return true;
}
#endif
typedef unique_lock<recursive_mutex> scoped_lock;
typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
};
typedef recursive_mutex recursive_try_mutex;
class recursive_timed_mutex
class recursive_timed_mutex:
boost::noncopyable
{
private:
recursive_timed_mutex(recursive_timed_mutex const&);
recursive_timed_mutex& operator=(recursive_timed_mutex const&);
private:
pthread_mutex_t m;
#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
pthread_cond_t cond;
bool is_locked;
pthread_t owner;
@@ -184,7 +106,7 @@ namespace boost
public:
recursive_timed_mutex()
{
#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
pthread_mutexattr_t attr;
int const init_attr_res=pthread_mutexattr_init(&attr);
@@ -224,7 +146,7 @@ namespace boost
~recursive_timed_mutex()
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
BOOST_VERIFY(!pthread_cond_destroy(&cond));
#endif
}
@@ -235,7 +157,7 @@ namespace boost
return timed_lock(get_system_time()+relative_time);
}
#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
void lock()
{
BOOST_VERIFY(!pthread_mutex_lock(&m));

View File

@@ -225,7 +225,7 @@ namespace boost
template<typename TimeDuration>
bool timed_lock_upgrade(TimeDuration const & relative_time)
{
return timed_lock_upgrade(get_system_time()+relative_time);
return timed_lock(get_system_time()+relative_time);
}
bool try_lock_upgrade()

View File

@@ -12,7 +12,6 @@
#include <boost/thread/mutex.hpp>
#include <boost/optional.hpp>
#include <pthread.h>
#include <boost/assert.hpp>
#include "condition_variable_fwd.hpp"
#include <map>
@@ -56,7 +55,6 @@ namespace boost
std::map<void const*,boost::detail::tss_data_node> tss_data;
bool interrupt_enabled;
bool interrupt_requested;
pthread_mutex_t* cond_mutex;
pthread_cond_t* current_cond;
thread_data_base():
@@ -78,8 +76,6 @@ namespace boost
class interruption_checker
{
thread_data_base* const thread_info;
pthread_mutex_t* m;
bool set;
void check_for_interruption()
{
@@ -92,35 +88,23 @@ namespace boost
void operator=(interruption_checker&);
public:
explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond):
thread_info(detail::get_current_thread_data()),m(cond_mutex),
set(thread_info && thread_info->interrupt_enabled)
explicit interruption_checker(pthread_cond_t* cond):
thread_info(detail::get_current_thread_data())
{
if(set)
if(thread_info && thread_info->interrupt_enabled)
{
lock_guard<mutex> guard(thread_info->data_mutex);
check_for_interruption();
thread_info->cond_mutex=cond_mutex;
thread_info->current_cond=cond;
BOOST_VERIFY(!pthread_mutex_lock(m));
}
else
{
BOOST_VERIFY(!pthread_mutex_lock(m));
}
}
~interruption_checker()
{
if(set)
if(thread_info && thread_info->interrupt_enabled)
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
lock_guard<mutex> guard(thread_info->data_mutex);
thread_info->cond_mutex=NULL;
thread_info->current_cond=NULL;
}
else
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
check_for_interruption();
}
}
};

View File

@@ -6,7 +6,6 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/date_time/time_clock.hpp>
#include <boost/date_time/microsec_time_clock.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
@@ -18,11 +17,7 @@ namespace boost
inline system_time get_system_time()
{
#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
return boost::date_time::microsec_clock<system_time>::universal_time();
#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
return boost::date_time::second_clock<system_time>::universal_time();
#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
}
namespace detail

View File

@@ -62,8 +62,6 @@ namespace boost
boost::shared_ptr<detail::tss_cleanup_function> cleanup;
public:
typedef T element_type;
thread_specific_ptr():
cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
{}

View File

@@ -20,11 +20,9 @@ namespace boost
}
class mutex:
boost::noncopyable,
public ::boost::detail::underlying_mutex
{
private:
mutex(mutex const&);
mutex& operator=(mutex const&);
public:
mutex()
{
@@ -42,11 +40,9 @@ namespace boost
typedef mutex try_mutex;
class timed_mutex:
boost::noncopyable,
public ::boost::detail::basic_timed_mutex
{
private:
timed_mutex(timed_mutex const&);
timed_mutex& operator=(timed_mutex const&);
public:
timed_mutex()
{

View File

@@ -34,85 +34,42 @@ namespace boost
{
long status;
long count;
long throw_count;
void* event_handle;
~once_flag()
{
if(count)
{
BOOST_ASSERT(count==throw_count);
}
void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event_handle,0);
if(old_event)
{
::boost::detail::win32::CloseHandle(old_event);
}
}
};
#define BOOST_ONCE_INIT {0,0}
#define BOOST_ONCE_INIT {0,0,0,0}
namespace detail
{
#ifdef BOOST_NO_ANSI_APIS
typedef wchar_t once_char_type;
#else
typedef char once_char_type;
#endif
unsigned const once_mutex_name_fixed_length=54;
unsigned const once_mutex_name_length=once_mutex_name_fixed_length+
sizeof(void*)*2+sizeof(unsigned long)*2+1;
template <class I>
void int_to_string(I p, once_char_type* buf)
inline void* allocate_event_handle(void*& handle)
{
for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
{
#ifdef BOOST_NO_ANSI_APIS
once_char_type const a=L'A';
#else
once_char_type const a='A';
#endif
*buf = a + static_cast<once_char_type>((p >> (i*4)) & 0x0f);
}
*buf = 0;
}
inline void name_once_mutex(once_char_type* mutex_name,void* flag_address)
{
#ifdef BOOST_NO_ANSI_APIS
static const once_char_type fixed_mutex_name[]=L"Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
#else
static const once_char_type fixed_mutex_name[]="Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
#endif
BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) ==
(sizeof(once_char_type)*(once_mutex_name_fixed_length+1)));
void* const new_handle=::boost::detail::win32::create_anonymous_event(
::boost::detail::win32::manual_reset_event,
::boost::detail::win32::event_initially_reset);
std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),
mutex_name + once_mutex_name_fixed_length);
detail::int_to_string(win32::GetCurrentProcessId(),
mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
}
inline void* open_once_event(once_char_type* mutex_name,void* flag_address)
{
if(!*mutex_name)
void* event_handle=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&handle,
new_handle,0);
if(event_handle)
{
name_once_mutex(mutex_name,flag_address);
::boost::detail::win32::CloseHandle(new_handle);
return event_handle;
}
#ifdef BOOST_NO_ANSI_APIS
return ::boost::detail::win32::OpenEventW(
#else
return ::boost::detail::win32::OpenEventA(
#endif
::boost::detail::win32::synchronize |
::boost::detail::win32::event_modify_state,
false,
mutex_name);
}
inline void* create_once_event(once_char_type* mutex_name,void* flag_address)
{
if(!*mutex_name)
{
name_once_mutex(mutex_name,flag_address);
}
#ifdef BOOST_NO_ANSI_APIS
return ::boost::detail::win32::CreateEventW(
#else
return ::boost::detail::win32::CreateEventA(
#endif
0,::boost::detail::win32::manual_reset_event,
::boost::detail::win32::event_initially_reset,
mutex_name);
return new_handle;
}
}
@@ -126,9 +83,8 @@ namespace boost
long const running_value=0x7f0725e3;
long status;
bool counted=false;
detail::win32::handle_manager event_handle;
detail::once_char_type mutex_name[detail::once_mutex_name_length];
mutex_name[0]=0;
void* event_handle=0;
long throw_count=0;
while((status=::boost::detail::interlocked_read_acquire(&flag.status))
!=function_complete_flag_value)
@@ -140,7 +96,7 @@ namespace boost
{
if(!event_handle)
{
event_handle=detail::open_once_event(mutex_name,&flag);
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
}
if(event_handle)
{
@@ -156,20 +112,25 @@ namespace boost
if(!event_handle &&
(::boost::detail::interlocked_read_acquire(&flag.count)>1))
{
event_handle=detail::create_once_event(mutex_name,&flag);
event_handle=::boost::detail::allocate_event_handle(flag.event_handle);
}
if(event_handle)
{
::boost::detail::win32::SetEvent(event_handle);
}
throw_count=::boost::detail::interlocked_read_acquire(&flag.throw_count);
break;
}
catch(...)
{
if(counted)
{
BOOST_INTERLOCKED_INCREMENT(&flag.throw_count);
}
BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
if(!event_handle)
{
event_handle=detail::open_once_event(mutex_name,&flag);
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
}
if(event_handle)
{
@@ -188,15 +149,31 @@ namespace boost
{
break;
}
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
if(!event_handle)
{
event_handle=detail::create_once_event(mutex_name,&flag);
event_handle=::boost::detail::allocate_event_handle(flag.event_handle);
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
event_handle,::boost::detail::win32::infinite));
}
if(counted || throw_count)
{
if(!BOOST_INTERLOCKED_EXCHANGE_ADD(&flag.count,(counted?-1:0)-throw_count))
{
if(!event_handle)
{
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
}
if(event_handle)
{
BOOST_INTERLOCKED_EXCHANGE_POINTER(&flag.event_handle,0);
::boost::detail::win32::CloseHandle(event_handle);
}
}
}
}
}

View File

@@ -20,11 +20,9 @@
namespace boost
{
class recursive_mutex:
boost::noncopyable,
public ::boost::detail::basic_recursive_mutex
{
private:
recursive_mutex(recursive_mutex const&);
recursive_mutex& operator=(recursive_mutex const&);
public:
recursive_mutex()
{
@@ -42,11 +40,9 @@ namespace boost
typedef recursive_mutex recursive_try_mutex;
class recursive_timed_mutex:
boost::noncopyable,
public ::boost::detail::basic_recursive_timed_mutex
{
private:
recursive_timed_mutex(recursive_timed_mutex const&);
recursive_timed_mutex& operator=(recursive_timed_mutex const&);
public:
recursive_timed_mutex()
{

View File

@@ -19,11 +19,9 @@
namespace boost
{
class shared_mutex
class shared_mutex:
private boost::noncopyable
{
private:
shared_mutex(shared_mutex const&);
shared_mutex& operator=(shared_mutex const&);
private:
struct state_data
{
@@ -51,35 +49,33 @@ namespace boost
return *reinterpret_cast<T const*>(&res);
}
enum
{
unlock_sem = 0,
exclusive_sem = 1
};
state_data state;
detail::win32::handle semaphores[2];
detail::win32::handle &unlock_sem;
detail::win32::handle &exclusive_sem;
detail::win32::handle upgrade_sem;
void release_waiters(state_data old_state)
{
if(old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
BOOST_VERIFY(detail::win32::ReleaseSemaphore(exclusive_sem,1,0)!=0);
}
if(old_state.shared_waiting || old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
BOOST_VERIFY(detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
}
}
public:
shared_mutex()
shared_mutex():
unlock_sem(semaphores[0]),
exclusive_sem(semaphores[1])
{
semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
state_data state_={0};
state=state_;
@@ -88,8 +84,8 @@ namespace boost
~shared_mutex()
{
detail::win32::CloseHandle(upgrade_sem);
detail::win32::CloseHandle(semaphores[unlock_sem]);
detail::win32::CloseHandle(semaphores[exclusive_sem]);
detail::win32::CloseHandle(unlock_sem);
detail::win32::CloseHandle(exclusive_sem);
}
bool try_lock_shared()
@@ -101,10 +97,6 @@ namespace boost
if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
@@ -139,18 +131,10 @@ namespace boost
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
++new_state.shared_waiting;
if(!new_state.shared_waiting)
{
boost::throw_exception(boost::lock_error());
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
boost::throw_exception(boost::lock_error());
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
@@ -166,7 +150,7 @@ namespace boost
return true;
}
unsigned long const res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until));
unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until));
if(res==detail::win32::timeout)
{
for(;;)
@@ -182,10 +166,6 @@ namespace boost
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
@@ -302,11 +282,6 @@ namespace boost
if(new_state.shared_count || new_state.exclusive)
{
++new_state.exclusive_waiting;
if(!new_state.exclusive_waiting)
{
boost::throw_exception(boost::lock_error());
}
new_state.exclusive_waiting_blocked=true;
}
else
@@ -399,18 +374,10 @@ namespace boost
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
{
++new_state.shared_waiting;
if(!new_state.shared_waiting)
{
boost::throw_exception(boost::lock_error());
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
boost::throw_exception(boost::lock_error());
}
new_state.upgrade=true;
}
@@ -427,7 +394,7 @@ namespace boost
return;
}
BOOST_VERIFY(!detail::win32::WaitForSingleObject(semaphores[unlock_sem],detail::win32::infinite));
BOOST_VERIFY(!detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite));
}
}
@@ -444,10 +411,6 @@ namespace boost
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
new_state.upgrade=true;
}

View File

@@ -144,11 +144,6 @@ namespace boost
start(0),milliseconds(~uintmax_t(0)),relative(true)
{}
};
inline unsigned long pin_to_zero(long value)
{
return (value<0)?0u:(unsigned long)value;
}
}
namespace this_thread
@@ -168,7 +163,7 @@ namespace boost
template<typename TimeDuration>
inline void sleep(TimeDuration const& rel_time)
{
interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
interruptible_wait(static_cast<unsigned long>(rel_time.total_milliseconds()));
}
inline void sleep(system_time const& abs_time)
{

View File

@@ -56,7 +56,7 @@ namespace boost
{
namespace detail
{
inline /*BOOST_THREAD_DECL*/ void* allocate_raw_heap_memory(unsigned size)
inline BOOST_THREAD_DECL void* allocate_raw_heap_memory(unsigned size)
{
void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size);
if(!heap_memory)
@@ -66,7 +66,7 @@ namespace boost
return heap_memory;
}
inline /*BOOST_THREAD_DECL*/ void free_raw_heap_memory(void* heap_memory)
inline BOOST_THREAD_DECL void free_raw_heap_memory(void* heap_memory)
{
BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0);
}

View File

@@ -31,18 +31,14 @@ namespace boost
unsigned const infinite=INFINITE;
unsigned const timeout=WAIT_TIMEOUT;
handle const invalid_handle_value=INVALID_HANDLE_VALUE;
unsigned const event_modify_state=EVENT_MODIFY_STATE;
unsigned const synchronize=SYNCHRONIZE;
# ifdef BOOST_NO_ANSI_APIS
using ::CreateMutexW;
using ::CreateEventW;
using ::OpenEventW;
using ::CreateSemaphoreW;
# else
using ::CreateMutexA;
using ::CreateEventA;
using ::OpenEventA;
using ::CreateSemaphoreA;
# endif
using ::CloseHandle;
@@ -104,8 +100,6 @@ namespace boost
unsigned const infinite=~0U;
unsigned const timeout=258U;
handle const invalid_handle_value=(handle)(-1);
unsigned const event_modify_state=2;
unsigned const synchronize=0x100000u;
extern "C"
{
@@ -114,12 +108,10 @@ namespace boost
__declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
__declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
# else
__declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
__declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
__declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
# endif
__declspec(dllimport) int __stdcall CloseHandle(void*);
__declspec(dllimport) int __stdcall ReleaseMutex(void*);

View File

@@ -75,7 +75,7 @@ namespace boost
{
current=next;
++next;
if(current->second.func && (current->second.value!=0))
if(current->second.func && current->second.value)
{
(*current->second.func)(current->second.value);
}
@@ -196,14 +196,15 @@ namespace boost
detach();
}
detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const
detail::thread_data_ptr thread::get_thread_info() const
{
lock_guard<mutex> l(thread_info_mutex);
return thread_info;
}
void thread::join()
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
bool do_join=false;
@@ -237,6 +238,7 @@ namespace boost
local_thread_info->done_condition.notify_all();
}
lock_guard<mutex> l1(thread_info_mutex);
if(thread_info==local_thread_info)
{
thread_info.reset();
@@ -246,7 +248,7 @@ namespace boost
bool thread::timed_join(system_time const& wait_until)
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
bool do_join=false;
@@ -283,6 +285,7 @@ namespace boost
local_thread_info->done_condition.notify_all();
}
lock_guard<mutex> l1(thread_info_mutex);
if(thread_info==local_thread_info)
{
thread_info.reset();
@@ -293,14 +296,17 @@ namespace boost
bool thread::joinable() const
{
return (get_thread_info)();
return get_thread_info();
}
void thread::detach()
{
detail::thread_data_ptr local_thread_info;
thread_info.swap(local_thread_info);
{
lock_guard<mutex> l1(thread_info_mutex);
thread_info.swap(local_thread_info);
}
if(local_thread_info)
{
@@ -375,6 +381,8 @@ namespace boost
{
#if defined(PTW32_VERSION) || defined(__hpux)
return pthread_num_processors_np();
#elif defined(_GNU_SOURCE)
return get_nprocs();
#elif defined(__APPLE__) || defined(__FreeBSD__)
int count;
size_t size=sizeof(count);
@@ -382,8 +390,6 @@ namespace boost
#elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN)
int const count=sysconf(_SC_NPROCESSORS_ONLN);
return (count>0)?count:0;
#elif defined(_GNU_SOURCE)
return get_nprocs();
#else
return 0;
#endif
@@ -391,7 +397,7 @@ namespace boost
thread::id thread::get_id() const
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
return id(local_thread_info);
@@ -404,14 +410,13 @@ namespace boost
void thread::interrupt()
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
lock_guard<mutex> lk(local_thread_info->data_mutex);
local_thread_info->interrupt_requested=true;
if(local_thread_info->current_cond)
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(local_thread_info->cond_mutex);
BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
}
}
@@ -419,7 +424,7 @@ namespace boost
bool thread::interruption_requested() const
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -433,7 +438,7 @@ namespace boost
thread::native_handle_type thread::native_handle()
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -577,11 +582,11 @@ namespace boost
{
if(tss_data_node* const current_node=find_tss_data(key))
{
if(cleanup_existing && current_node->func && (current_node->value!=0))
if(cleanup_existing && current_node->func && current_node->value)
{
(*current_node->func)(current_node->value);
}
if(func || (tss_data!=0))
if(func || tss_data)
{
current_node->func=func;
current_node->value=tss_data;

View File

@@ -8,15 +8,13 @@
#if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE))
namespace boost
{
/*
This file is a "null" implementation of tss cleanup; it's
purpose is to to eliminate link errors in cases
where it is known that tss cleanup is not needed.
*/
void tss_cleanup_implemented(void)
extern "C" void tss_cleanup_implemented(void)
{
/*
This function's sole purpose is to cause a link error in cases where
@@ -32,7 +30,5 @@ namespace boost
longer needed and can be removed.
*/
}
}
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER)

View File

@@ -56,10 +56,7 @@ namespace boost
void set_current_thread_data(detail::thread_data_base* new_data)
{
boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
if(current_thread_tls_key)
BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data));
else
boost::throw_exception(thread_resource_error());
BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data));
}
#ifdef BOOST_NO_THREADEX
@@ -224,15 +221,7 @@ namespace boost
void make_external_thread_data()
{
externally_launched_thread* me=detail::heap_new<externally_launched_thread>();
try
{
set_current_thread_data(me);
}
catch(...)
{
detail::heap_delete(me);
throw;
}
set_current_thread_data(me);
}
detail::thread_data_base* get_or_make_current_thread_data()
@@ -255,17 +244,17 @@ namespace boost
thread::id thread::get_id() const
{
return thread::id((get_thread_info)());
return thread::id(get_thread_info());
}
bool thread::joinable() const
{
return (get_thread_info)();
return get_thread_info();
}
void thread::join()
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
if(local_thread_info)
{
this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel());
@@ -275,7 +264,7 @@ namespace boost
bool thread::timed_join(boost::system_time const& wait_until)
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
if(local_thread_info)
{
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,get_milliseconds_until(wait_until)))
@@ -294,12 +283,13 @@ namespace boost
void thread::release_handle()
{
lock_guard<mutex> l1(thread_info_mutex);
thread_info=0;
}
void thread::interrupt()
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
if(local_thread_info)
{
local_thread_info->interrupt();
@@ -308,25 +298,26 @@ namespace boost
bool thread::interruption_requested() const
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0);
}
unsigned thread::hardware_concurrency()
{
SYSTEM_INFO info={{0}};
SYSTEM_INFO info={0};
GetSystemInfo(&info);
return info.dwNumberOfProcessors;
}
thread::native_handle_type thread::native_handle()
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
return local_thread_info?(detail::win32::handle)local_thread_info->thread_handle:detail::win32::invalid_handle_value;
}
detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const
detail::thread_data_ptr thread::get_thread_info() const
{
boost::mutex::scoped_lock l(thread_info_mutex);
return thread_info;
}
@@ -336,7 +327,7 @@ namespace boost
{
LARGE_INTEGER get_due_time(detail::timeout const& target_time)
{
LARGE_INTEGER due_time={{0}};
LARGE_INTEGER due_time={0};
if(target_time.relative)
{
unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start;
@@ -365,23 +356,7 @@ namespace boost
else
{
long const hundred_nanoseconds_in_one_second=10000000;
posix_time::time_duration::tick_type const ticks_per_second=
target_time.abs_time.time_of_day().ticks_per_second();
if(ticks_per_second>hundred_nanoseconds_in_one_second)
{
posix_time::time_duration::tick_type const
ticks_per_hundred_nanoseconds=
ticks_per_second/hundred_nanoseconds_in_one_second;
due_time.QuadPart+=
target_time.abs_time.time_of_day().fractional_seconds()/
ticks_per_hundred_nanoseconds;
}
else
{
due_time.QuadPart+=
target_time.abs_time.time_of_day().fractional_seconds()*
(hundred_nanoseconds_in_one_second/ticks_per_second);
}
due_time.QuadPart+=target_time.abs_time.time_of_day().fractional_seconds()*(hundred_nanoseconds_in_one_second/target_time.abs_time.time_of_day().ticks_per_second());
}
}
return due_time;
@@ -551,8 +526,8 @@ namespace boost
{
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
thread_exit_callback_node* const new_node=
heap_new<thread_exit_callback_node>(
func,current_thread_data->thread_exit_callbacks);
heap_new<thread_exit_callback_node>(func,
current_thread_data->thread_exit_callbacks);
current_thread_data->thread_exit_callbacks=new_node;
}
@@ -594,31 +569,30 @@ namespace boost
current_node->func=func;
current_node->value=tss_data;
}
else if(func && tss_data)
else
{
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
tss_data_node* const new_node=
heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data);
tss_data_node* const new_node=heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data);
current_thread_data->tss_data=new_node;
}
}
}
BOOST_THREAD_DECL void __cdecl on_process_enter()
{}
BOOST_THREAD_DECL void __cdecl on_thread_enter()
{}
BOOST_THREAD_DECL void __cdecl on_process_exit()
{
boost::cleanup_tls_key();
}
BOOST_THREAD_DECL void __cdecl on_thread_exit()
{
boost::run_thread_exit_callbacks();
}
}
extern "C" BOOST_THREAD_DECL void on_process_enter()
{}
extern "C" BOOST_THREAD_DECL void on_thread_enter()
{}
extern "C" BOOST_THREAD_DECL void on_process_exit()
{
boost::cleanup_tls_key();
}
extern "C" BOOST_THREAD_DECL void on_thread_exit()
{
boost::run_thread_exit_callbacks();
}

View File

@@ -24,27 +24,27 @@
{
case DLL_PROCESS_ATTACH:
{
boost::on_process_enter();
boost::on_thread_enter();
on_process_enter();
on_thread_enter();
break;
}
case DLL_THREAD_ATTACH:
{
boost::on_thread_enter();
on_thread_enter();
break;
}
case DLL_THREAD_DETACH:
{
boost::on_thread_exit();
on_thread_exit();
break;
}
case DLL_PROCESS_DETACH:
{
boost::on_thread_exit();
boost::on_process_exit();
on_thread_exit();
on_process_exit();
break;
}
}
@@ -52,9 +52,7 @@
return TRUE;
}
namespace boost
{
void tss_cleanup_implemented()
extern "C" void tss_cleanup_implemented(void)
{
/*
This function's sole purpose is to cause a link error in cases where
@@ -70,7 +68,5 @@ namespace boost
longer needed and can be removed.
*/
}
}
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)

View File

@@ -19,10 +19,7 @@
#include <cstdlib>
namespace boost
{
void tss_cleanup_implemented() {}
}
extern "C" void tss_cleanup_implemented(void) {}
namespace {
void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv)
@@ -31,24 +28,33 @@ namespace {
{
case DLL_THREAD_DETACH:
{
boost::on_thread_exit();
on_thread_exit();
break;
}
}
}
void on_after_ctors(void)
{
on_process_enter();
}
void on_before_dtors(void)
{
on_thread_exit();
}
void on_after_dtors(void)
{
on_process_exit();
}
}
#if (__MINGW32_MAJOR_VERSION >3) || ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
extern "C"
{
PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
}
#else
extern "C" {
void (* after_ctors )() __attribute__((section(".ctors"))) = boost::on_process_enter;
void (* before_dtors)() __attribute__((section(".dtors"))) = boost::on_thread_exit;
void (* after_dtors )() __attribute__((section(".dtors.zzz"))) = boost::on_process_exit;
void (* after_ctors )(void) __attribute__((section(".ctors"))) = on_after_ctors;
void (* before_dtors)(void) __attribute__((section(".dtors"))) = on_before_dtors;
void (* after_dtors )(void) __attribute__((section(".dtors.zzz"))) = on_after_dtors;
ULONG __tls_index__ = 0;
char __tls_end__ __attribute__((section(".tls$zzz"))) = 0;
@@ -56,8 +62,10 @@ extern "C" {
PIMAGE_TLS_CALLBACK __crt_xl_start__ __attribute__ ((section(".CRT$XLA"))) = 0;
PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
PIMAGE_TLS_CALLBACK __crt_xl_end__ __attribute__ ((section(".CRT$XLZ"))) = 0;
}
extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata$T"))) =
{
(DWORD) &__tls_start__,
@@ -67,7 +75,6 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
(DWORD) 0,
(DWORD) 0
};
#endif
#elif defined(_MSC_VER) && !defined(UNDER_CE)
@@ -82,13 +89,13 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
//Definitions required by implementation
#if (_MSC_VER < 1300) // 1300 == VC++ 7.0
typedef void (__cdecl *_PVFV)();
typedef void (__cdecl *_PVFV)(void);
#define INIRETSUCCESS
#define PVAPI void __cdecl
#define PVAPI void
#else
typedef int (__cdecl *_PVFV)();
typedef int (__cdecl *_PVFV)(void);
#define INIRETSUCCESS 0
#define PVAPI int __cdecl
#define PVAPI int
#endif
typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
@@ -105,9 +112,9 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
{
//Forward declarations
static PVAPI on_tls_prepare();
static PVAPI on_process_init();
static PVAPI on_process_term();
static PVAPI on_tls_prepare(void);
static PVAPI on_process_init(void);
static PVAPI on_process_term(void);
static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
//The .CRT$Xxx information is taken from Codeguru:
@@ -162,7 +169,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
#pragma warning(disable:4189)
#endif
PVAPI on_tls_prepare()
PVAPI on_tls_prepare(void)
{
//The following line has an important side effect:
//if the TLS directory is not already there, it will
@@ -203,7 +210,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
#pragma warning(pop)
#endif
PVAPI on_process_init()
PVAPI on_process_init(void)
{
//Schedule on_thread_exit() to be called for the main
//thread before destructors of global objects have been
@@ -214,18 +221,18 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
//for destructors of global objects, so that
//shouldn't be a problem.
atexit(boost::on_thread_exit);
atexit(on_thread_exit);
//Call Boost process entry callback here
boost::on_process_enter();
on_process_enter();
return INIRETSUCCESS;
}
PVAPI on_process_term()
PVAPI on_process_term(void)
{
boost::on_process_exit();
on_process_exit();
return INIRETSUCCESS;
}
@@ -234,7 +241,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
switch (dwReason)
{
case DLL_THREAD_DETACH:
boost::on_thread_exit();
on_thread_exit();
break;
}
}
@@ -244,10 +251,10 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
switch (dwReason)
{
case DLL_THREAD_DETACH:
boost::on_thread_exit();
on_thread_exit();
break;
case DLL_PROCESS_DETACH:
boost::on_process_exit();
on_process_exit();
break;
}
return true;
@@ -258,9 +265,8 @@ extern "C"
{
extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;
}
namespace boost
{
void tss_cleanup_implemented()
extern "C" void tss_cleanup_implemented(void)
{
/*
This function's sole purpose is to cause a link error in cases where
@@ -276,8 +282,6 @@ namespace boost
longer needed and can be removed.
*/
}
}
#endif //defined(_MSC_VER) && !defined(UNDER_CE)
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)

View File

@@ -18,7 +18,7 @@
template<typename T>
typename boost::remove_reference<T>::type&& cast_to_rval(T&& t)
{
return static_cast<typename boost::remove_reference<T>::type&&>(t);
return t;
}
#else
template<typename T>
@@ -556,7 +556,7 @@ void wait_callback(boost::promise<int>& pi)
}
}
void do_nothing_callback(boost::promise<int>& /*pi*/)
void do_nothing_callback(boost::promise<int>& pi)
{
boost::lock_guard<boost::mutex> lk(callback_mutex);
++callback_called;
@@ -1041,8 +1041,6 @@ void test_wait_for_any_from_range()
}
boost::thread(::cast_to_rval(tasks[i]));
BOOST_CHECK(boost::wait_for_any(futures,futures)==futures);
boost::unique_future<int>* const future=boost::wait_for_any(futures,futures+count);
BOOST_CHECK(future==(futures+i));

View File

@@ -296,80 +296,10 @@ void test_lock_five_in_range()
}
}
class dummy_iterator:
public std::iterator<std::forward_iterator_tag,
dummy_mutex>
{
private:
dummy_mutex* p;
public:
explicit dummy_iterator(dummy_mutex* p_):
p(p_)
{}
bool operator==(dummy_iterator const& other) const
{
return p==other.p;
}
bool operator!=(dummy_iterator const& other) const
{
return p!=other.p;
}
bool operator<(dummy_iterator const& other) const
{
return p<other.p;
}
dummy_mutex& operator*() const
{
return *p;
}
dummy_mutex* operator->() const
{
return p;
}
dummy_iterator operator++(int)
{
dummy_iterator temp(*this);
++p;
return temp;
}
dummy_iterator& operator++()
{
++p;
return *this;
}
};
void test_lock_five_in_range_custom_iterator()
{
unsigned const num_mutexes=5;
dummy_mutex mutexes[num_mutexes];
boost::lock(dummy_iterator(mutexes),dummy_iterator(mutexes+num_mutexes));
for(unsigned i=0;i<num_mutexes;++i)
{
BOOST_CHECK(mutexes[i].is_locked);
}
}
class dummy_mutex2:
public dummy_mutex
{};
void test_lock_ten_in_range_inherited_mutex()
void test_lock_ten_in_range()
{
unsigned const num_mutexes=10;
dummy_mutex2 mutexes[num_mutexes];
dummy_mutex mutexes[num_mutexes];
boost::lock(mutexes,mutexes+num_mutexes);
@@ -580,8 +510,7 @@ boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_order));
test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_different_order));
test->add(BOOST_TEST_CASE(&test_lock_five_in_range));
test->add(BOOST_TEST_CASE(&test_lock_five_in_range_custom_iterator));
test->add(BOOST_TEST_CASE(&test_lock_ten_in_range_inherited_mutex));
test->add(BOOST_TEST_CASE(&test_lock_ten_in_range));
test->add(BOOST_TEST_CASE(&test_lock_ten_other_thread_locks_in_different_order));
test->add(BOOST_TEST_CASE(&test_try_lock_two_uncontended));
test->add(BOOST_TEST_CASE(&test_try_lock_two_first_locked));

View File

@@ -138,14 +138,6 @@ void test_can_lock_upgrade_if_currently_locked_shared()
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count+1);
}
void test_can_lock_upgrade_to_unique_if_currently_locked_upgrade()
{
boost::shared_mutex mtx;
boost::upgrade_lock<boost::shared_mutex> l(mtx);
boost::upgrade_to_unique_lock<boost::shared_mutex> ul(l);
BOOST_CHECK(ul.owns_lock());
}
void test_if_other_thread_has_write_lock_try_lock_shared_returns_false()
{
@@ -290,7 +282,6 @@ boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(&test_only_one_upgrade_lock_permitted));
test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_if_currently_locked_shared));
test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_to_unique_if_currently_locked_upgrade));
test->add(BOOST_TEST_CASE(&test_if_other_thread_has_write_lock_try_lock_shared_returns_false));
test->add(BOOST_TEST_CASE(&test_if_no_thread_has_lock_try_lock_shared_returns_true));
test->add(BOOST_TEST_CASE(&test_if_other_thread_has_shared_lock_try_lock_shared_returns_true));