summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/thread/win32')
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp4
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp17
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp54
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/mutex.hpp9
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/once.hpp956
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp9
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp37
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_data.hpp79
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp101
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp95
10 files changed, 1206 insertions, 155 deletions
diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp
index e259121..cfdfa04 100644
--- a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp
@@ -55,22 +55,24 @@ namespace boost
{
mutex.lock();
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
recursion_count=1;
}
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(::boost::system_time const& target)
{
long const current_thread_id=win32::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
}
template<typename Duration>
bool timed_lock(Duration const& timeout)
{
return timed_lock(get_system_time()+timeout);
}
+#endif
#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();
@@ -111,22 +113,24 @@ namespace boost
recursion_count=1;
return true;
}
return false;
}
+#if defined BOOST_THREAD_USES_DATETIME
bool try_timed_lock(long current_thread_id,::boost::system_time const& target)
{
if(mutex.timed_lock(target))
{
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
recursion_count=1;
return true;
}
return false;
}
+#endif
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);
diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp
index 6a43077..01db033 100644
--- a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp
@@ -11,13 +11,15 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <boost/thread/thread_time.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
#include <boost/thread/xtime.hpp>
+#endif
#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>
@@ -76,28 +78,33 @@ namespace boost
{
bool lock_acquired=false;
void* const sem=get_event();
do
{
- BOOST_VERIFY(win32::WaitForSingleObject(
- sem,::boost::detail::win32::infinite)==0);
+ unsigned const retval(win32::WaitForSingleObject(sem, ::boost::detail::win32::infinite));
+ BOOST_VERIFY(0 == retval || ::boost::detail::win32::wait_abandoned == retval);
+// BOOST_VERIFY(win32::WaitForSingleObject(
+// sem,::boost::detail::win32::infinite)==0);
clear_waiting_and_try_lock(old_count);
lock_acquired=!(old_count&lock_flag_value);
}
while(!lock_acquired);
}
}
void mark_waiting_and_try_lock(long& old_count)
{
for(;;)
{
- long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value);
+ bool const was_locked=(old_count&lock_flag_value) ? true : false;
+ long const new_count=was_locked?(old_count+1):(old_count|lock_flag_value);
long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
if(current==old_count)
{
+ if(was_locked)
+ old_count=new_count;
break;
}
old_count=current;
}
}
@@ -115,12 +122,13 @@ namespace boost
}
old_count=current;
}
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(::boost::system_time const& wait_until)
{
if(try_lock())
{
return true;
}
@@ -144,24 +152,23 @@ namespace boost
}
while(!lock_acquired);
}
return true;
}
-
template<typename Duration>
bool timed_lock(Duration const& timeout)
{
return timed_lock(get_system_time()+timeout);
}
bool timed_lock(boost::xtime const& timeout)
{
return timed_lock(system_time(timeout));
}
-
+#endif
#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);
}
diff --git a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp
index 4c893ad..57aaf8c 100644
--- a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp
@@ -8,15 +8,19 @@
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/thread_data.hpp>
#include <boost/thread/win32/thread_data.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <boost/thread/cv_status.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
#include <boost/thread/xtime.hpp>
+#endif
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread_time.hpp>
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/lock_types.hpp>
#include <boost/assert.hpp>
#include <boost/intrusive_ptr.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
@@ -184,24 +188,23 @@ namespace boost
}
}
struct entry_manager
{
entry_ptr const entry;
+ boost::mutex& internal_mutex;
BOOST_THREAD_NO_COPYABLE(entry_manager)
- entry_manager(entry_ptr const& entry_):
- entry(entry_)
+ entry_manager(entry_ptr const& entry_, boost::mutex& mutex_):
+ entry(entry_), internal_mutex(mutex_)
{}
~entry_manager()
{
- if(! entry->is_notified())
- {
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
entry->remove_waiter();
- }
}
list_entry* operator->()
{
return entry.get();
}
@@ -211,13 +214,13 @@ namespace boost
protected:
template<typename lock_type>
bool do_wait(lock_type& lock,timeout abs_time)
{
relocker<lock_type> locker(lock);
- entry_manager entry(get_wait_entry());
+ entry_manager entry(get_wait_entry(), internal_mutex);
locker.unlock();
bool woken=false;
while(!woken)
{
@@ -318,25 +321,35 @@ namespace boost
void wait(unique_lock<mutex>& m,predicate_type pred)
{
while(!pred()) wait(m);
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time)
{
return do_wait(m,abs_time);
}
bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time)
{
return do_wait(m,system_time(abs_time));
}
template<typename duration_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
{
- return do_wait(m,wait_duration.total_milliseconds());
+ if (wait_duration.is_pos_infinity())
+ {
+ wait(m); // or do_wait(m,detail::timeout::sentinel());
+ return true;
+ }
+ if (wait_duration.is_special())
+ {
+ return true;
+ }
+ return do_wait(m,wait_duration.total_milliseconds());
}
template<typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time,predicate_type pred)
{
return do_wait(m,abs_time,pred);
@@ -348,34 +361,42 @@ namespace boost
}
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);
}
-
+#endif
#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());
+ chrono::time_point<Clock, Duration> now = Clock::now();
+ if (t<=now) {
+ return cv_status::timeout;
+ }
+ do_wait(lock, ceil<milliseconds>(t-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;
+ if (d<=chrono::duration<Rep, Period>::zero()) {
+ return cv_status::timeout;
+ }
+
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;
}
@@ -397,13 +418,13 @@ namespace boost
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);
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
}
#endif
};
class condition_variable_any:
private detail::basic_condition_variable
@@ -425,12 +446,13 @@ namespace boost
template<typename lock_type,typename predicate_type>
void wait(lock_type& m,predicate_type pred)
{
while(!pred()) wait(m);
}
+#if defined BOOST_THREAD_USES_DATETIME
template<typename lock_type>
bool timed_wait(lock_type& m,boost::system_time const& abs_time)
{
return do_wait(m,abs_time);
}
@@ -460,33 +482,41 @@ namespace boost
template<typename lock_type,typename duration_type,typename predicate_type>
bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
{
return do_wait(m,wait_duration.total_milliseconds(),pred);
}
+#endif
#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());
+ chrono::time_point<Clock, Duration> now = Clock::now();
+ if (t<=now) {
+ return cv_status::timeout;
+ }
+ do_wait(lock, ceil<milliseconds>(t-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;
+ if (d<=chrono::duration<Rep, Period>::zero()) {
+ return cv_status::timeout;
+ }
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;
}
@@ -509,13 +539,13 @@ namespace boost
bool
wait_for(
lock_type& lock,
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
- return wait_until(lock, chrono::steady_clock::now() + d, pred);
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
}
#endif
};
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
}
diff --git a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp
index 85a00e2..0154478 100644
--- a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp
@@ -5,13 +5,16 @@
// 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/thread/exceptions.hpp>
-#include <boost/thread/locks.hpp>
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/lock_types.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace detail
@@ -30,14 +33,16 @@ namespace boost
}
~mutex()
{
destroy();
}
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
typedef unique_lock<mutex> scoped_lock;
typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
+#endif
};
typedef mutex try_mutex;
class timed_mutex:
public ::boost::detail::basic_timed_mutex
@@ -51,15 +56,17 @@ namespace boost
~timed_mutex()
{
destroy();
}
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
typedef unique_lock<timed_mutex> scoped_timed_lock;
typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
typedef scoped_timed_lock scoped_lock;
+#endif
};
}
#include <boost/config/abi_suffix.hpp>
#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/once.hpp b/3rdParty/Boost/src/boost/thread/win32/once.hpp
index 3066b50..0ed56a5 100644
--- a/3rdParty/Boost/src/boost/thread/win32/once.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/once.hpp
@@ -2,25 +2,30 @@
#define BOOST_THREAD_WIN32_ONCE_HPP
// once.hpp
//
// (C) Copyright 2005-7 Anthony Williams
// (C) Copyright 2005 John Maddock
-// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+// (C) Copyright 2011-2013 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 <cstring>
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/interlocked.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
+
+#include <boost/bind.hpp>
#include <boost/config/abi_prefix.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std
{
@@ -28,26 +33,36 @@ namespace std
using ::ptrdiff_t;
}
#endif
namespace boost
{
+ struct once_flag;
+ namespace detail
+ {
+ struct once_context;
+
+ inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
+ inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
+ inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
+ }
+
#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);
+ private:
+ friend inline bool enter_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
+ friend inline void commit_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
+ friend inline void rollback_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
};
#define BOOST_ONCE_INIT once_flag()
#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
struct once_flag
@@ -56,12 +71,23 @@ namespace boost
long count;
};
#define BOOST_ONCE_INIT {0,0}
#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#else
+#define BOOST_THREAD_INVOKE_RET_VOID boost::bind
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
+#endif
+
namespace detail
{
#ifdef BOOST_NO_ANSI_APIS
typedef wchar_t once_char_type;
#else
typedef char once_char_type;
@@ -132,99 +158,933 @@ namespace boost
return ::boost::detail::win32::CreateEventA(
#endif
0,::boost::detail::win32::manual_reset_event,
::boost::detail::win32::event_initially_reset,
mutex_name);
}
- }
+ struct once_context {
+ long const function_complete_flag_value;
+ long const running_value;
+ bool counted;
+ detail::win32::handle_manager event_handle;
+ detail::once_char_type mutex_name[once_mutex_name_length];
+ once_context() :
+ function_complete_flag_value(0xc15730e2),
+ running_value(0x7f0725e3),
+ counted(false)
+ {
+ mutex_name[0]=0;
+ }
+ };
+ enum once_action {try_, break_, continue_};
+ inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
+ {
+ long status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,ctx.running_value,0);
+ if(!status)
+ {
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag);
+ }
+ if(ctx.event_handle)
+ {
+ ::boost::detail::win32::ResetEvent(ctx.event_handle);
+ }
+ return true;
+ }
+ return false;
+ }
+ inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
+ {
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ }
+ BOOST_INTERLOCKED_EXCHANGE(&flag.status,ctx.function_complete_flag_value);
+ if(!ctx.event_handle &&
+ (::boost::detail::interlocked_read_acquire(&flag.count)>1))
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ }
+ if(ctx.event_handle)
+ {
+ ::boost::detail::win32::SetEvent(ctx.event_handle);
+ }
+ }
+ inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag);
+ }
+ if(ctx.event_handle)
+ {
+ ::boost::detail::win32::SetEvent(ctx.event_handle);
+ }
+ }
+ }
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+ inline void call_once(once_flag& flag, void (*f)())
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+//#endif
+ template<typename Function>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, class A, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(A) a, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<A>(a)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+#else
+#if ! defined(BOOST_MSVC) && ! defined(BOOST_INTEL)
template<typename Function>
void call_once(once_flag& flag,Function f)
{
// Try for a quick win: if the procedure has already been called
// just skip through:
- long const function_complete_flag_value=0xc15730e2;
- 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;
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1>
+ void call_once(once_flag& flag,Function f, T1 p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,Function f, T1 p1, T2 p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,Function f, T1 p1, T2 p2, T3 p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+#elif defined BOOST_NO_CXX11_RVALUE_REFERENCES
- while((status=::boost::detail::interlocked_read_acquire(&flag.status))
- !=function_complete_flag_value)
+ template<typename Function>
+ void call_once(once_flag& flag,Function const&f)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
{
- status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0);
- if(!status)
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
{
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1>
+ void call_once(once_flag& flag,Function const&f, T1 const&p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2, T3 const&p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
#endif
+#if 1
+#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+ inline void call_once(once_flag& flag, void (*f)())
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
{
- if(!event_handle)
+ BOOST_TRY
{
- event_handle=detail::open_once_event(mutex_name,&flag);
+ f();
}
- if(event_handle)
+ BOOST_CATCH(...)
{
- ::boost::detail::win32::ResetEvent(event_handle);
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
}
- f();
- if(!counted)
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename T1>
+ void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1)), BOOST_THREAD_RV_REF(T1) p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ );
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
{
- BOOST_INTERLOCKED_INCREMENT(&flag.count);
- counted=true;
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2))
+ );
}
- BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value);
- if(!event_handle &&
- (::boost::detail::interlocked_read_acquire(&flag.count)>1))
+ BOOST_CATCH(...)
{
- event_handle=detail::create_once_event(mutex_name,&flag);
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
}
- if(event_handle)
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
{
- ::boost::detail::win32::SetEvent(event_handle);
+ break;
}
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2)),
+ thread_detail::decay_copy(boost::forward<T3>(p3))
+ );
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
break;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ if(!ctx.counted)
{
- BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
- if(!event_handle)
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
{
- event_handle=detail::open_once_event(mutex_name,&flag);
+ break;
}
- if(event_handle)
+ if(!ctx.event_handle)
{
- ::boost::detail::win32::SetEvent(event_handle);
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
}
- throw; // BOOST_NO_EXCEPTIONS protected
}
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
#endif
+ template<typename Function>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
}
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
- if(!counted)
+ template<typename Function, typename T1>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
{
BOOST_INTERLOCKED_INCREMENT(&flag.count);
- counted=true;
- status=::boost::detail::interlocked_read_acquire(&flag.status);
- if(status==function_complete_flag_value)
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
{
break;
}
- if(!event_handle)
+ if(!ctx.event_handle)
{
- event_handle=detail::create_once_event(mutex_name,&flag);
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
- event_handle,::boost::detail::win32::infinite));
+ ctx.event_handle,::boost::detail::win32::infinite));
}
}
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2)),
+ thread_detail::decay_copy(boost::forward<T3>(p3))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+
+#endif
+#endif
}
#include <boost/config/abi_suffix.hpp>
#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp
index 5144e77..1f0f7f5 100644
--- a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp
@@ -9,13 +9,16 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/win32/basic_recursive_mutex.hpp>
#include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.hpp>
+#include <boost/thread/detail/delete.hpp>
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/lock_types.hpp>
+#endif
#include <boost/config/abi_prefix.hpp>
namespace boost
{
class recursive_mutex:
@@ -29,14 +32,16 @@ namespace boost
}
~recursive_mutex()
{
::boost::detail::basic_recursive_mutex::destroy();
}
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
typedef unique_lock<recursive_mutex> scoped_lock;
typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
+#endif
};
typedef recursive_mutex recursive_try_mutex;
class recursive_timed_mutex:
public ::boost::detail::basic_recursive_timed_mutex
@@ -49,15 +54,17 @@ namespace boost
}
~recursive_timed_mutex()
{
::boost::detail::basic_recursive_timed_mutex::destroy();
}
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;
typedef scoped_timed_lock scoped_lock;
+#endif
};
}
#include <boost/config/abi_suffix.hpp>
#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp
index fef2d5b..252174f 100644
--- a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp
@@ -92,13 +92,13 @@ namespace boost
if (!upgrade_sem)
{
detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX);
boost::throw_exception(thread_resource_error());
}
- state_data state_={0};
+ state_data state_={0,0,0,0,0,0};
state=state_;
}
~shared_mutex()
{
detail::win32::CloseHandle(upgrade_sem);
@@ -130,21 +130,25 @@ namespace boost
}
return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
}
void lock_shared()
{
+#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
+#else
+ BOOST_VERIFY(try_lock_shared_until(chrono::steady_clock::now()));
+#endif
}
+#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
bool timed_lock_shared(TimeDuration const & relative_time)
{
return timed_lock_shared(get_system_time()+relative_time);
}
-
bool timed_lock_shared(boost::system_time const& wait_until)
{
for(;;)
{
state_data old_state=state;
for(;;)
@@ -217,12 +221,13 @@ namespace boost
return false;
}
BOOST_ASSERT(res==0);
}
}
+#endif
#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);
@@ -375,20 +380,26 @@ namespace boost
old_state=current_state;
}
}
void lock()
{
+#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
+#else
+ BOOST_VERIFY(try_lock_until(chrono::steady_clock::now()));
+#endif
}
+#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
return timed_lock(get_system_time()+relative_time);
}
+#endif
bool try_lock()
{
state_data old_state=state;
for(;;)
{
@@ -410,12 +421,13 @@ namespace boost
old_state=current_state;
}
return true;
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(boost::system_time const& wait_until)
{
for(;;)
{
state_data old_state=state;
@@ -456,29 +468,36 @@ namespace boost
#endif
unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until));
if(wait_res==detail::win32::timeout)
{
for(;;)
{
+ bool must_notify = false;
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;
+ must_notify = true;
}
}
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if (must_notify)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
+ }
+
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
@@ -488,13 +507,13 @@ namespace boost
}
return false;
}
BOOST_ASSERT(wait_res<2);
}
}
-
+#endif
#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);
}
@@ -565,29 +584,35 @@ namespace boost
wait_res=detail::win32::timeout;
}
if(wait_res==detail::win32::timeout)
{
for(;;)
{
+ bool must_notify = false;
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;
+ must_notify = true;
}
}
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if (must_notify)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
+ }
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
@@ -721,15 +746,17 @@ namespace boost
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
if(last_reader)
{
release_waiters(old_state);
- } else {
- release_waiters(old_state);
}
+ // #7720
+ //else {
+ // release_waiters(old_state);
+ //}
break;
}
old_state=current_state;
}
}
diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp
index 18fd7cb..1d4f572 100644
--- a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp
@@ -19,12 +19,17 @@
#include <map>
#include <vector>
#include <utility>
#include <boost/config/abi_prefix.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+
namespace boost
{
class condition_variable;
class mutex;
class thread_attributes {
@@ -64,12 +69,13 @@ namespace boost
private:
win_attrs val_;
};
namespace detail
{
+ struct shared_state_base;
struct tss_cleanup_function;
struct thread_exit_callback_node;
struct tss_data_node
{
boost::shared_ptr<boost::detail::tss_cleanup_function> func;
void* value;
@@ -85,30 +91,40 @@ namespace boost
void intrusive_ptr_release(thread_data_base * p);
struct BOOST_THREAD_DECL thread_data_base
{
long count;
detail::win32::handle_manager thread_handle;
- detail::win32::handle_manager interruption_handle;
boost::detail::thread_exit_callback_node* thread_exit_callbacks;
std::map<void const*,boost::detail::tss_data_node> tss_data;
- bool interruption_enabled;
unsigned id;
typedef std::vector<std::pair<condition_variable*, mutex*>
//, hidden_allocator<std::pair<condition_variable*, mutex*> >
> notify_list_t;
notify_list_t notify;
+ typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
+ async_states_t async_states_;
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ // These data must be at the end so that the access to the other fields doesn't change
+ // when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined
+ // Another option is to have them always
+ detail::win32::handle_manager interruption_handle;
+ bool interruption_enabled;
+//#endif
thread_data_base():
count(0),thread_handle(detail::win32::invalid_handle_value),
- interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
thread_exit_callbacks(0),tss_data(),
- interruption_enabled(true),
id(0),
- notify()
+ notify(),
+ async_states_()
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ , interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset))
+ , interruption_enabled(true)
+//#endif
{}
virtual ~thread_data_base();
friend void intrusive_ptr_add_ref(thread_data_base * p)
{
BOOST_INTERLOCKED_INCREMENT(&p->count);
@@ -119,48 +135,55 @@ namespace boost
if(!BOOST_INTERLOCKED_DECREMENT(&p->count))
{
detail::heap_delete(p);
}
}
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
void interrupt()
{
BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);
}
-
+#endif
typedef detail::win32::handle native_handle_type;
virtual void run()=0;
- void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
+ virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
{
notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
}
+ void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
+ {
+ async_states_.push_back(as);
+ }
+
};
+ BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
struct BOOST_SYMBOL_VISIBLE timeout
{
- unsigned long start;
+ win32::ticks_type start;
uintmax_t milliseconds;
bool relative;
boost::system_time abs_time;
static unsigned long const max_non_infinite_wait=0xfffffffe;
timeout(uintmax_t milliseconds_):
- start(win32::GetTickCount()),
+ start(win32::GetTickCount64()()),
milliseconds(milliseconds_),
relative(true),
abs_time(boost::get_system_time())
{}
timeout(boost::system_time const& abs_time_):
- start(win32::GetTickCount()),
+ start(win32::GetTickCount64()()),
milliseconds(0),
relative(false),
abs_time(abs_time_)
{}
struct BOOST_SYMBOL_VISIBLE remaining_time
@@ -179,14 +202,14 @@ namespace boost
if(is_sentinel())
{
return remaining_time(win32::infinite);
}
else if(relative)
{
- unsigned long const now=win32::GetTickCount();
- unsigned long const elapsed=now-start;
+ win32::ticks_type const now=win32::GetTickCount64()();
+ win32::ticks_type const elapsed=now-start;
return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0);
}
else
{
system_time const now=get_system_time();
if(abs_time<=now)
@@ -232,13 +255,12 @@ namespace boost
interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
}
inline BOOST_SYMBOL_VISIBLE void interruptible_wait(system_time const& abs_time)
{
interruptible_wait(detail::win32::invalid_handle_value,abs_time);
}
-
template<typename TimeDuration>
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
{
interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
}
inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)
@@ -248,13 +270,44 @@ namespace boost
#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
+ namespace no_interruption_point
+ {
+ bool BOOST_THREAD_DECL non_interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
+ inline void non_interruptible_wait(uintmax_t milliseconds)
+ {
+ non_interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
+ }
+ inline BOOST_SYMBOL_VISIBLE void non_interruptible_wait(system_time const& abs_time)
+ {
+ non_interruptible_wait(detail::win32::invalid_handle_value,abs_time);
+ }
+ template<typename TimeDuration>
+ inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
+ {
+ non_interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
+ }
+ inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)
+ {
+ non_interruptible_wait(abs_time);
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+ {
+ non_interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
+ }
+#endif
+ }
}
}
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
#include <boost/config/abi_suffix.hpp>
#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp
index 9b6d390..610fe32 100644
--- a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp
@@ -2,16 +2,18 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
#ifndef THREAD_HEAP_ALLOC_HPP
#define THREAD_HEAP_ALLOC_HPP
#include <new>
+#include <boost/thread/detail/config.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <stdexcept>
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
+#include <boost/core/no_exceptions_support.hpp>
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
namespace boost
{
@@ -72,186 +74,159 @@ namespace boost
}
template<typename T>
inline T* heap_new()
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T();
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<typename T,typename A1>
inline T* heap_new(A1&& a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
static_cast<A3&&>(a3));
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
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;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
#else
template<typename T,typename A1>
inline T* heap_new_impl(A1 a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(a1);
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(a1,a2);
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(a1,a2,a3);
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(a1,a2,a3,a4);
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
template<typename T,typename A1>
inline T* heap_new(A1 const& a1)
{
diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp
index c0dba11..fcf59b3 100644
--- a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp
@@ -12,30 +12,32 @@
#include <boost/thread/detail/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/detail/interlocked.hpp>
+//#include <boost/detail/winapi/synchronization.hpp>
#include <algorithm>
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
namespace boost
{
namespace detail
{
namespace win32
{
- typedef ULONG_PTR ulong_ptr;
typedef HANDLE handle;
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;
+ unsigned const wait_abandoned=WAIT_ABANDONED;
+
# ifdef BOOST_NO_ANSI_APIS
using ::CreateMutexW;
using ::CreateEventW;
using ::OpenEventW;
using ::CreateSemaphoreW;
@@ -57,13 +59,12 @@ namespace boost
using ::GetCurrentThread;
using ::GetCurrentProcess;
using ::DuplicateHandle;
using ::SleepEx;
using ::Sleep;
using ::QueueUserAPC;
- using ::GetTickCount;
}
}
}
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
# ifdef UNDER_CE
@@ -85,30 +86,31 @@ typedef void* HANDLE;
# include <kfuncs.h>
# ifdef __cplusplus
}
# endif
# endif
+
namespace boost
{
namespace detail
{
namespace win32
{
-
# ifdef _WIN64
typedef unsigned __int64 ulong_ptr;
# else
typedef unsigned long ulong_ptr;
# endif
typedef void* handle;
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;
+ unsigned const wait_abandoned=0x00000080u;
extern "C"
{
struct _SECURITY_ATTRIBUTES;
# ifdef BOOST_NO_ANSI_APIS
__declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
@@ -129,14 +131,12 @@ namespace boost
__declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
__declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int);
__declspec(dllimport) void __stdcall Sleep(unsigned long);
typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
__declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
- __declspec(dllimport) unsigned long __stdcall GetTickCount();
-
# ifndef UNDER_CE
__declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
__declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
__declspec(dllimport) void* __stdcall GetCurrentThread();
__declspec(dllimport) void* __stdcall GetCurrentProcess();
__declspec(dllimport) int __stdcall SetEvent(void*);
@@ -162,13 +162,94 @@ namespace boost
namespace boost
{
namespace detail
{
namespace win32
{
- enum event_type
+ typedef unsigned __int64 ticks_type;
+ namespace detail { typedef int (__stdcall *farproc_t)(); typedef ticks_type (__stdcall *gettickcount64_t)(); }
+ extern "C"
+ {
+ __declspec(dllimport) detail::farproc_t __stdcall GetProcAddress(void *, const char *);
+#if !defined(BOOST_NO_ANSI_APIS)
+ __declspec(dllimport) void * __stdcall GetModuleHandleA(const char *);
+#else
+ __declspec(dllimport) void * __stdcall GetModuleHandleW(const wchar_t *);
+#endif
+ int __stdcall GetTickCount();
+ long _InterlockedCompareExchange(long volatile *, long, long);
+#pragma intrinsic(_InterlockedCompareExchange)
+ }
+ // Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar
+ inline ticks_type __stdcall GetTickCount64emulation()
+ {
+ static volatile long count = 0xFFFFFFFF;
+ unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone;
+ ticks_type current_tick64;
+
+ previous_count = (unsigned long) _InterlockedCompareExchange(&count, 0, 0);
+ current_tick32 = GetTickCount();
+
+ if(previous_count == 0xFFFFFFFF)
+ {
+ // count has never been written
+ unsigned long initial_count;
+ initial_count = current_tick32 >> 28;
+ previous_count = (unsigned long) _InterlockedCompareExchange(&count, initial_count, 0xFFFFFFFF);
+
+ current_tick64 = initial_count;
+ current_tick64 <<= 28;
+ current_tick64 += current_tick32 & 0x0FFFFFFF;
+ return current_tick64;
+ }
+
+ previous_count_zone = previous_count & 15;
+ current_tick32_zone = current_tick32 >> 28;
+
+ if(current_tick32_zone == previous_count_zone)
+ {
+ // The top four bits of the 32-bit tick count haven't changed since count was last written.
+ current_tick64 = previous_count;
+ current_tick64 <<= 28;
+ current_tick64 += current_tick32 & 0x0FFFFFFF;
+ return current_tick64;
+ }
+
+ if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15))
+ {
+ // The top four bits of the 32-bit tick count have been incremented since count was last written.
+ _InterlockedCompareExchange(&count, previous_count + 1, previous_count);
+ current_tick64 = previous_count + 1;
+ current_tick64 <<= 28;
+ current_tick64 += current_tick32 & 0x0FFFFFFF;
+ return current_tick64;
+ }
+
+ // Oops, we weren't called often enough, we're stuck
+ return 0xFFFFFFFF;
+ }
+ inline detail::gettickcount64_t GetTickCount64()
+ {
+ static detail::gettickcount64_t gettickcount64impl;
+ if(gettickcount64impl)
+ return gettickcount64impl;
+ detail::farproc_t addr=GetProcAddress(
+#if !defined(BOOST_NO_ANSI_APIS)
+ GetModuleHandleA("KERNEL32.DLL"),
+#else
+ GetModuleHandleW(L"KERNEL32.DLL"),
+#endif
+ "GetTickCount64");
+ if(addr)
+ gettickcount64impl=(detail::gettickcount64_t) addr;
+ else
+ gettickcount64impl=&GetTickCount64emulation;
+ return gettickcount64impl;
+ }
+
+ enum event_type
{
auto_reset_event=false,
manual_reset_event=true
};
enum initial_event_state
@@ -229,13 +310,13 @@ namespace boost
inline void release_semaphore(handle semaphore,long count)
{
BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
}
- class handle_manager
+ class BOOST_THREAD_DECL handle_manager
{
private:
handle handle_to_manage;
handle_manager(handle_manager&);
handle_manager& operator=(handle_manager&);