summaryrefslogtreecommitdiff
path: root/boost/thread/win32
diff options
context:
space:
mode:
Diffstat (limited to 'boost/thread/win32')
-rw-r--r--boost/thread/win32/basic_recursive_mutex.hpp42
-rw-r--r--boost/thread/win32/basic_timed_mutex.hpp60
-rw-r--r--boost/thread/win32/condition_variable.hpp181
-rw-r--r--boost/thread/win32/mutex.hpp10
-rw-r--r--boost/thread/win32/once.hpp55
-rw-r--r--boost/thread/win32/recursive_mutex.hpp9
-rw-r--r--boost/thread/win32/shared_mutex.hpp256
-rw-r--r--boost/thread/win32/thread_data.hpp51
-rw-r--r--boost/thread/win32/thread_heap_alloc.hpp90
-rw-r--r--boost/thread/win32/thread_primitives.hpp20
10 files changed, 668 insertions, 106 deletions
diff --git a/boost/thread/win32/basic_recursive_mutex.hpp b/boost/thread/win32/basic_recursive_mutex.hpp
index e748aa725c..eb5ec8489d 100644
--- a/boost/thread/win32/basic_recursive_mutex.hpp
+++ b/boost/thread/win32/basic_recursive_mutex.hpp
@@ -4,6 +4,7 @@
// basic_recursive_mutex.hpp
//
// (C) Copyright 2006-8 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -11,6 +12,10 @@
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/basic_timed_mutex.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
#include <boost/config/abi_prefix.hpp>
@@ -64,6 +69,20 @@ namespace boost
return timed_lock(get_system_time()+timeout);
}
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ long const current_thread_id=win32::GetCurrentThreadId();
+ return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ long const current_thread_id=win32::GetCurrentThreadId();
+ return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t);
+ }
+#endif
void unlock()
{
if(!--recursion_count)
@@ -105,7 +124,28 @@ namespace boost
}
return false;
}
-
+ template <typename TP>
+ bool try_timed_lock_until(long current_thread_id,TP const& target)
+ {
+ if(mutex.try_lock_until(target))
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+ recursion_count=1;
+ return true;
+ }
+ return false;
+ }
+ template <typename D>
+ bool try_timed_lock_for(long current_thread_id,D const& target)
+ {
+ if(mutex.try_lock_for(target))
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+ recursion_count=1;
+ return true;
+ }
+ return false;
+ }
};
typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex;
diff --git a/boost/thread/win32/basic_timed_mutex.hpp b/boost/thread/win32/basic_timed_mutex.hpp
index a88c2a0f6f..30580e7c17 100644
--- a/boost/thread/win32/basic_timed_mutex.hpp
+++ b/boost/thread/win32/basic_timed_mutex.hpp
@@ -4,6 +4,7 @@
// basic_timed_mutex_win32.hpp
//
// (C) Copyright 2006-8 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -15,7 +16,10 @@
#include <boost/thread/thread_time.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/detail/interlocked.hpp>
-
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
#include <boost/config/abi_prefix.hpp>
namespace boost
@@ -143,6 +147,7 @@ namespace boost
return true;
}
+
template<typename Duration>
bool timed_lock(Duration const& timeout)
{
@@ -154,6 +159,59 @@ namespace boost
return timed_lock(system_time(timeout));
}
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
+ }
+ template <class Duration>
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
+ return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
+ }
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
+ {
+ if(try_lock())
+ {
+ return true;
+ }
+ long old_count=active_count;
+ mark_waiting_and_try_lock(old_count);
+
+ if(old_count&lock_flag_value)
+ {
+ bool lock_acquired=false;
+ void* const sem=get_event();
+
+ do
+ {
+ chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
+
+ if(win32::WaitForSingleObject(sem,static_cast<unsigned long>(rel_time.count()))!=0)
+ {
+ BOOST_INTERLOCKED_DECREMENT(&active_count);
+ return false;
+ }
+ clear_waiting_and_try_lock(old_count);
+ lock_acquired=!(old_count&lock_flag_value);
+ }
+ while(!lock_acquired);
+ }
+ return true;
+ }
+#endif
+
void unlock()
{
long const offset=lock_flag_value;
diff --git a/boost/thread/win32/condition_variable.hpp b/boost/thread/win32/condition_variable.hpp
index 056bda8086..63f830b186 100644
--- a/boost/thread/win32/condition_variable.hpp
+++ b/boost/thread/win32/condition_variable.hpp
@@ -4,18 +4,24 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007-8 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#include <boost/thread/mutex.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <limits.h>
#include <boost/assert.hpp>
#include <algorithm>
-#include <boost/thread/thread.hpp>
+#include <boost/thread/cv_status.hpp>
+#include <boost/thread/win32/thread_data.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <boost/thread/xtime.hpp>
#include <vector>
#include <boost/intrusive_ptr.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
#include <boost/config/abi_prefix.hpp>
@@ -36,10 +42,8 @@ namespace boost
bool notified;
long references;
- basic_cv_list_entry(basic_cv_list_entry&);
- void operator=(basic_cv_list_entry&);
-
public:
+ BOOST_THREAD_NO_COPYABLE(basic_cv_list_entry)
explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_):
semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)),
wake_sem(wake_sem_.duplicate()),
@@ -77,9 +81,9 @@ namespace boost
return notified;
}
- bool wait(timeout wait_until)
+ bool wait(timeout abs_time)
{
- return this_thread::interruptible_wait(semaphore,wait_until);
+ return this_thread::interruptible_wait(semaphore,abs_time);
}
bool woken()
@@ -129,6 +133,7 @@ namespace boost
template<typename lock_type>
struct relocker
{
+ BOOST_THREAD_NO_COPYABLE(relocker)
lock_type& lock;
bool unlocked;
@@ -148,9 +153,6 @@ namespace boost
}
}
- private:
- relocker(relocker&);
- void operator=(relocker&);
};
@@ -182,6 +184,7 @@ namespace boost
{
entry_ptr const entry;
+ BOOST_THREAD_NO_COPYABLE(entry_manager)
entry_manager(entry_ptr const& entry_):
entry(entry_)
{}
@@ -195,16 +198,12 @@ namespace boost
{
return entry.get();
}
-
- private:
- void operator=(entry_manager&);
- entry_manager(entry_manager&);
};
protected:
template<typename lock_type>
- bool do_wait(lock_type& lock,timeout wait_until)
+ bool do_wait(lock_type& lock,timeout abs_time)
{
relocker<lock_type> locker(lock);
@@ -215,7 +214,7 @@ namespace boost
bool woken=false;
while(!woken)
{
- if(!entry->wait(wait_until))
+ if(!entry->wait(abs_time))
{
return false;
}
@@ -226,11 +225,11 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
- bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred)
+ bool do_wait(lock_type& m,timeout const& abs_time,predicate_type pred)
{
while (!pred())
{
- if(!do_wait(m, wait_until))
+ if(!do_wait(m, abs_time))
return pred();
}
return true;
@@ -247,7 +246,7 @@ namespace boost
~basic_condition_variable()
{}
- void notify_one()
+ void notify_one() BOOST_NOEXCEPT
{
if(detail::interlocked_read_acquire(&total_count))
{
@@ -268,7 +267,7 @@ namespace boost
}
}
- void notify_all()
+ void notify_all() BOOST_NOEXCEPT
{
if(detail::interlocked_read_acquire(&total_count))
{
@@ -295,10 +294,8 @@ namespace boost
class condition_variable:
private detail::basic_condition_variable
{
- private:
- condition_variable(condition_variable&);
- void operator=(condition_variable&);
public:
+ BOOST_THREAD_NO_COPYABLE(condition_variable)
condition_variable()
{}
@@ -317,14 +314,14 @@ namespace boost
}
- bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
+ bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time)
{
- return do_wait(m,wait_until);
+ return do_wait(m,abs_time);
}
- bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until)
+ bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time)
{
- return do_wait(m,system_time(wait_until));
+ return do_wait(m,system_time(abs_time));
}
template<typename duration_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
@@ -333,29 +330,79 @@ namespace boost
}
template<typename predicate_type>
- bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)
+ bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time,predicate_type pred)
{
- return do_wait(m,wait_until,pred);
+ return do_wait(m,abs_time,pred);
}
template<typename predicate_type>
- bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred)
+ bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time,predicate_type pred)
{
- return do_wait(m,system_time(wait_until),pred);
+ return do_wait(m,system_time(abs_time),pred);
}
template<typename duration_type,typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
{
return do_wait(m,wait_duration.total_milliseconds(),pred);
}
+
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Clock, class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ do_wait(lock, ceil<milliseconds>(t-Clock::now()).count());
+ return Clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class Rep, class Period>
+ cv_status
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ steady_clock::time_point c_now = steady_clock::now();
+ do_wait(lock, ceil<milliseconds>(d).count());
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+ template <class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ return wait_until(lock, chrono::steady_clock::now() + d, pred);
+ }
+#endif
};
class condition_variable_any:
private detail::basic_condition_variable
{
- private:
- condition_variable_any(condition_variable_any&);
- void operator=(condition_variable_any&);
public:
+ BOOST_THREAD_NO_COPYABLE(condition_variable_any)
condition_variable_any()
{}
@@ -375,15 +422,15 @@ namespace boost
}
template<typename lock_type>
- bool timed_wait(lock_type& m,boost::system_time const& wait_until)
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time)
{
- return do_wait(m,wait_until);
+ return do_wait(m,abs_time);
}
template<typename lock_type>
- bool timed_wait(lock_type& m,boost::xtime const& wait_until)
+ bool timed_wait(lock_type& m,boost::xtime const& abs_time)
{
- return do_wait(m,system_time(wait_until));
+ return do_wait(m,system_time(abs_time));
}
template<typename lock_type,typename duration_type>
@@ -393,15 +440,15 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
- bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time,predicate_type pred)
{
- return do_wait(m,wait_until,pred);
+ return do_wait(m,abs_time,pred);
}
template<typename lock_type,typename predicate_type>
- bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred)
+ bool timed_wait(lock_type& m,boost::xtime const& abs_time,predicate_type pred)
{
- return do_wait(m,system_time(wait_until),pred);
+ return do_wait(m,system_time(abs_time),pred);
}
template<typename lock_type,typename duration_type,typename predicate_type>
@@ -409,6 +456,58 @@ namespace boost
{
return do_wait(m,wait_duration.total_milliseconds(),pred);
}
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class lock_type, class Clock, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ do_wait(lock, ceil<milliseconds>(t-Clock::now()).count());
+ return Clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class lock_type, class Rep, class Period>
+ cv_status
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ steady_clock::time_point c_now = steady_clock::now();
+ do_wait(lock, ceil<milliseconds>(d).count());
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class lock_type, class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ template <class lock_type, class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ return wait_until(lock, chrono::steady_clock::now() + d, pred);
+ }
+#endif
};
}
diff --git a/boost/thread/win32/mutex.hpp b/boost/thread/win32/mutex.hpp
index 92b2669e49..85a00e29f9 100644
--- a/boost/thread/win32/mutex.hpp
+++ b/boost/thread/win32/mutex.hpp
@@ -1,12 +1,12 @@
#ifndef BOOST_THREAD_WIN32_MUTEX_HPP
#define BOOST_THREAD_WIN32_MUTEX_HPP
// (C) Copyright 2005-7 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
// 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)
#include <boost/thread/win32/basic_timed_mutex.hpp>
-#include <boost/utility.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/locks.hpp>
@@ -22,10 +22,8 @@ namespace boost
class mutex:
public ::boost::detail::underlying_mutex
{
- private:
- mutex(mutex const&);
- mutex& operator=(mutex const&);
public:
+ BOOST_THREAD_NO_COPYABLE(mutex)
mutex()
{
initialize();
@@ -44,10 +42,8 @@ namespace boost
class timed_mutex:
public ::boost::detail::basic_timed_mutex
{
- private:
- timed_mutex(timed_mutex const&);
- timed_mutex& operator=(timed_mutex const&);
public:
+ BOOST_THREAD_NO_COPYABLE(timed_mutex)
timed_mutex()
{
initialize();
diff --git a/boost/thread/win32/once.hpp b/boost/thread/win32/once.hpp
index e1b1843230..3066b50bc3 100644
--- a/boost/thread/win32/once.hpp
+++ b/boost/thread/win32/once.hpp
@@ -3,8 +3,9 @@
// once.hpp
//
-// (C) Copyright 2005-7 Anthony Williams
+// (C) Copyright 2005-7 Anthony Williams
// (C) Copyright 2005 John Maddock
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -30,6 +31,25 @@ namespace std
namespace boost
{
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+ struct once_flag
+ {
+ BOOST_THREAD_NO_COPYABLE(once_flag)
+ BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
+ : status(0), count(0)
+ {}
+ private:
+ long status;
+ long count;
+ template<typename Function>
+ friend
+ void call_once(once_flag& flag,Function f);
+ };
+
+#define BOOST_ONCE_INIT once_flag()
+#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
+
struct once_flag
{
long status;
@@ -37,6 +57,7 @@ namespace boost
};
#define BOOST_ONCE_INIT {0,0}
+#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
namespace detail
{
@@ -71,29 +92,29 @@ namespace boost
#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) ==
+ BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) ==
(sizeof(once_char_type)*(once_mutex_name_fixed_length+1)));
-
+
std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
- detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),
+ detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),
mutex_name + once_mutex_name_fixed_length);
- detail::int_to_string(win32::GetCurrentProcessId(),
+ 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)
{
name_once_mutex(mutex_name,flag_address);
}
-
-#ifdef BOOST_NO_ANSI_APIS
+
+#ifdef BOOST_NO_ANSI_APIS
return ::boost::detail::win32::OpenEventW(
#else
return ::boost::detail::win32::OpenEventA(
#endif
- ::boost::detail::win32::synchronize |
+ ::boost::detail::win32::synchronize |
::boost::detail::win32::event_modify_state,
false,
mutex_name);
@@ -105,7 +126,7 @@ namespace boost
{
name_once_mutex(mutex_name,flag_address);
}
-#ifdef BOOST_NO_ANSI_APIS
+#ifdef BOOST_NO_ANSI_APIS
return ::boost::detail::win32::CreateEventW(
#else
return ::boost::detail::win32::CreateEventA(
@@ -115,7 +136,7 @@ namespace boost
mutex_name);
}
}
-
+
template<typename Function>
void call_once(once_flag& flag,Function f)
@@ -136,7 +157,9 @@ namespace boost
status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0);
if(!status)
{
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
if(!event_handle)
{
@@ -153,7 +176,7 @@ namespace boost
counted=true;
}
BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value);
- if(!event_handle &&
+ if(!event_handle &&
(::boost::detail::interlocked_read_acquire(&flag.count)>1))
{
event_handle=detail::create_once_event(mutex_name,&flag);
@@ -164,7 +187,8 @@ namespace boost
}
break;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
if(!event_handle)
@@ -175,8 +199,9 @@ namespace boost
{
::boost::detail::win32::SetEvent(event_handle);
}
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
if(!counted)
diff --git a/boost/thread/win32/recursive_mutex.hpp b/boost/thread/win32/recursive_mutex.hpp
index 7832bf270d..5144e77aa7 100644
--- a/boost/thread/win32/recursive_mutex.hpp
+++ b/boost/thread/win32/recursive_mutex.hpp
@@ -10,7 +10,6 @@
// http://www.boost.org/LICENSE_1_0.txt)
-#include <boost/utility.hpp>
#include <boost/thread/win32/basic_recursive_mutex.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/locks.hpp>
@@ -22,10 +21,8 @@ namespace boost
class recursive_mutex:
public ::boost::detail::basic_recursive_mutex
{
- private:
- recursive_mutex(recursive_mutex const&);
- recursive_mutex& operator=(recursive_mutex const&);
public:
+ BOOST_THREAD_NO_COPYABLE(recursive_mutex)
recursive_mutex()
{
::boost::detail::basic_recursive_mutex::initialize();
@@ -44,10 +41,8 @@ namespace boost
class recursive_timed_mutex:
public ::boost::detail::basic_recursive_timed_mutex
{
- private:
- recursive_timed_mutex(recursive_timed_mutex const&);
- recursive_timed_mutex& operator=(recursive_timed_mutex const&);
public:
+ BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex)
recursive_timed_mutex()
{
::boost::detail::basic_recursive_timed_mutex::initialize();
diff --git a/boost/thread/win32/shared_mutex.hpp b/boost/thread/win32/shared_mutex.hpp
index aee40399e4..fef2d5badd 100644
--- a/boost/thread/win32/shared_mutex.hpp
+++ b/boost/thread/win32/shared_mutex.hpp
@@ -2,6 +2,7 @@
#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
// (C) Copyright 2006-8 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,8 +13,12 @@
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/static_assert.hpp>
#include <limits.h>
-#include <boost/utility.hpp>
#include <boost/thread/thread_time.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -22,9 +27,6 @@ namespace boost
class shared_mutex
{
private:
- shared_mutex(shared_mutex const&);
- shared_mutex& operator=(shared_mutex const&);
- private:
struct state_data
{
unsigned shared_count:11,
@@ -76,6 +78,7 @@ namespace boost
public:
+ BOOST_THREAD_NO_COPYABLE(shared_mutex)
shared_mutex()
{
semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
@@ -218,6 +221,115 @@ namespace boost
}
}
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ return try_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now));
+ }
+ template <class Duration>
+ bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
+ return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
+ }
+ bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
+ {
+ for(;;)
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ 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);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+ {
+ return true;
+ }
+
+ chrono::system_clock::time_point n = chrono::system_clock::now();
+ unsigned long res;
+ if (tp>n) {
+ chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n);
+ res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],
+ static_cast<unsigned long>(rel_time.count()));
+ } else {
+ res=detail::win32::timeout;
+ }
+ if(res==detail::win32::timeout)
+ {
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+ {
+ if(new_state.shared_waiting)
+ {
+ --new_state.shared_waiting;
+ }
+ }
+ 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);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ BOOST_ASSERT(res==0);
+ }
+ }
+#endif
+
void unlock_shared()
{
state_data old_state=state;
@@ -380,6 +492,116 @@ namespace boost
}
}
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
+ }
+ template <class Duration>
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
+ return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
+ }
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
+ {
+ for(;;)
+ {
+ state_data old_state=state;
+
+ for(;;)
+ {
+ state_data new_state=old_state;
+ 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
+ {
+ 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;
+ }
+
+ if(!old_state.shared_count && !old_state.exclusive)
+ {
+ return true;
+ }
+ #ifndef UNDER_CE
+ const bool wait_all = true;
+ #else
+ const bool wait_all = false;
+ #endif
+
+ chrono::system_clock::time_point n = chrono::system_clock::now();
+ unsigned long wait_res;
+ if (tp>n) {
+ chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
+ wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all,
+ static_cast<unsigned long>(rel_time.count()));
+ } else {
+ wait_res=detail::win32::timeout;
+ }
+ if(wait_res==detail::win32::timeout)
+ {
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.shared_count || new_state.exclusive)
+ {
+ if(new_state.exclusive_waiting)
+ {
+ if(!--new_state.exclusive_waiting)
+ {
+ new_state.exclusive_waiting_blocked=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;
+ }
+ if(!old_state.shared_count && !old_state.exclusive)
+ {
+ return true;
+ }
+ return false;
+ }
+ BOOST_ASSERT(wait_res<2);
+ }
+ }
+#endif
+
void unlock()
{
state_data old_state=state;
@@ -502,6 +724,8 @@ namespace boost
if(last_reader)
{
release_waiters(old_state);
+ } else {
+ release_waiters(old_state);
}
break;
}
@@ -561,6 +785,27 @@ namespace boost
}
release_waiters(old_state);
}
+// bool try_unlock_upgrade_and_lock()
+// {
+// return false;
+// }
+//#ifdef BOOST_THREAD_USES_CHRONO
+// template <class Rep, class Period>
+// bool
+// try_unlock_upgrade_and_lock_for(
+// const chrono::duration<Rep, Period>& rel_time)
+// {
+// return try_unlock_upgrade_and_lock_until(
+// chrono::steady_clock::now() + rel_time);
+// }
+// template <class Clock, class Duration>
+// bool
+// try_unlock_upgrade_and_lock_until(
+// const chrono::time_point<Clock, Duration>& abs_time)
+// {
+// return false;
+// }
+//#endif
void unlock_and_lock_shared()
{
@@ -586,7 +831,6 @@ namespace boost
}
release_waiters(old_state);
}
-
void unlock_upgrade_and_lock_shared()
{
state_data old_state=state;
@@ -612,6 +856,8 @@ namespace boost
}
};
+ typedef shared_mutex upgrade_mutex;
+
}
#include <boost/config/abi_suffix.hpp>
diff --git a/boost/thread/win32/thread_data.hpp b/boost/thread/win32/thread_data.hpp
index d5303d897d..5af4fd3ed3 100644
--- a/boost/thread/win32/thread_data.hpp
+++ b/boost/thread/win32/thread_data.hpp
@@ -4,17 +4,58 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2008 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#include <boost/thread/detail/config.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/thread_heap_alloc.hpp>
-
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#endif
#include <boost/config/abi_prefix.hpp>
namespace boost
{
+ class thread_attributes {
+ public:
+ thread_attributes() BOOST_NOEXCEPT {
+ val_.stack_size = 0;
+ //val_.lpThreadAttributes=0;
+ }
+ ~thread_attributes() {
+ }
+ // stack size
+ void set_stack_size(std::size_t size) BOOST_NOEXCEPT {
+ val_.stack_size = size;
+ }
+
+ std::size_t get_stack_size() const BOOST_NOEXCEPT {
+ return val_.stack_size;
+ }
+
+ //void set_security(LPSECURITY_ATTRIBUTES lpThreadAttributes)
+ //{
+ // val_.lpThreadAttributes=lpThreadAttributes;
+ //}
+ //LPSECURITY_ATTRIBUTES get_security()
+ //{
+ // return val_.lpThreadAttributes;
+ //}
+
+ struct win_attrs {
+ std::size_t stack_size;
+ //LPSECURITY_ATTRIBUTES lpThreadAttributes;
+ };
+ typedef win_attrs native_handle_type;
+ native_handle_type* native_handle() {return &val_;}
+ const native_handle_type* native_handle() const {return &val_;}
+
+ private:
+ win_attrs val_;
+ };
+
namespace detail
{
struct thread_exit_callback_node;
@@ -153,7 +194,7 @@ namespace boost
namespace this_thread
{
- void BOOST_THREAD_DECL yield();
+ void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
inline void interruptible_wait(uintmax_t milliseconds)
@@ -174,6 +215,12 @@ namespace boost
{
interruptible_wait(abs_time);
}
+#ifdef BOOST_THREAD_USES_CHRONO
+ inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+ {
+ interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
+ }
+#endif
}
}
diff --git a/boost/thread/win32/thread_heap_alloc.hpp b/boost/thread/win32/thread_heap_alloc.hpp
index b7d329f31c..843e46b532 100644
--- a/boost/thread/win32/thread_heap_alloc.hpp
+++ b/boost/thread/win32/thread_heap_alloc.hpp
@@ -75,16 +75,20 @@ namespace boost
inline T* heap_new()
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
T* const data=new (heap_memory) T();
return data;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
#ifndef BOOST_NO_RVALUE_REFERENCES
@@ -92,127 +96,159 @@ namespace boost
inline T* heap_new(A1&& a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
return data;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
template<typename T,typename A1,typename A2>
inline T* heap_new(A1&& a1,A2&& a2)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
return data;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
template<typename T,typename A1,typename A2,typename A3>
inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
static_cast<A3&&>(a3));
return data;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
template<typename T,typename A1,typename A2,typename A3,typename A4>
inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
static_cast<A3&&>(a3),static_cast<A4&&>(a4));
return data;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
#else
template<typename T,typename A1>
inline T* heap_new_impl(A1 a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
T* const data=new (heap_memory) T(a1);
return data;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
template<typename T,typename A1,typename A2>
inline T* heap_new_impl(A1 a1,A2 a2)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
T* const data=new (heap_memory) T(a1,a2);
return data;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
template<typename T,typename A1,typename A2,typename A3>
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
T* const data=new (heap_memory) T(a1,a2,a3);
return data;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
template<typename T,typename A1,typename A2,typename A3,typename A4>
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
T* const data=new (heap_memory) T(a1,a2,a3,a4);
return data;
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
diff --git a/boost/thread/win32/thread_primitives.hpp b/boost/thread/win32/thread_primitives.hpp
index 0166f37d36..294e42ee9b 100644
--- a/boost/thread/win32/thread_primitives.hpp
+++ b/boost/thread/win32/thread_primitives.hpp
@@ -341,22 +341,42 @@ namespace boost
{
inline bool interlocked_bit_test_and_set(long* x,long bit)
{
+#if 0
__asm {
mov eax,bit;
mov edx,x;
lock bts [edx],eax;
setc al;
};
+#else
+ bool ret;
+ __asm {
+ mov eax,bit; mov edx,x; lock bts [edx],eax; setc al; mov ret, al
+ };
+ return ret;
+
+#endif
}
inline bool interlocked_bit_test_and_reset(long* x,long bit)
{
+#if 0
__asm {
mov eax,bit;
mov edx,x;
lock btr [edx],eax;
setc al;
};
+#else
+
+
+ bool ret;
+ __asm {
+ mov eax,bit; mov edx,x; lock btr [edx],eax; setc al; mov ret, al
+ };
+ return ret;
+
+#endif
}
}