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.hpp120
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp178
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp418
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp80
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/mutex.hpp65
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/once.hpp136
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp64
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp566
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_data.hpp178
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp397
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp398
11 files changed, 2600 insertions, 0 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
new file mode 100644
index 0000000..05eb8d7
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp
@@ -0,0 +1,120 @@
+#ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
+#define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
+
+// basic_recursive_mutex.hpp
+//
+// (C) Copyright 2006-8 Anthony Williams
+//
+// 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 "thread_primitives.hpp"
+#include "basic_timed_mutex.hpp"
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ template<typename underlying_mutex_type>
+ struct basic_recursive_mutex_impl
+ {
+ long recursion_count;
+ long locking_thread_id;
+ underlying_mutex_type mutex;
+
+ void initialize()
+ {
+ recursion_count=0;
+ locking_thread_id=0;
+ mutex.initialize();
+ }
+
+ void destroy()
+ {
+ mutex.destroy();
+ }
+
+ bool try_lock()
+ {
+ long const current_thread_id=win32::GetCurrentThreadId();
+ return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
+ }
+
+ void lock()
+ {
+ long const current_thread_id=win32::GetCurrentThreadId();
+ if(!try_recursive_lock(current_thread_id))
+ {
+ mutex.lock();
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+ recursion_count=1;
+ }
+ }
+ 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);
+ }
+
+ void unlock()
+ {
+ if(!--recursion_count)
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0);
+ mutex.unlock();
+ }
+ }
+
+ private:
+ bool try_recursive_lock(long current_thread_id)
+ {
+ if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id)
+ {
+ ++recursion_count;
+ return true;
+ }
+ return false;
+ }
+
+ bool try_basic_lock(long current_thread_id)
+ {
+ if(mutex.try_lock())
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+ recursion_count=1;
+ return true;
+ }
+ return false;
+ }
+
+ 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;
+ }
+
+ };
+
+ typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex;
+ typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex;
+ }
+}
+
+#define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp
new file mode 100644
index 0000000..751bdbd
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp
@@ -0,0 +1,178 @@
+#ifndef BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
+#define BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
+
+// basic_timed_mutex_win32.hpp
+//
+// (C) Copyright 2006-8 Anthony Williams
+//
+// 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/assert.hpp>
+#include "thread_primitives.hpp"
+#include "interlocked_read.hpp"
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/detail/interlocked.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ struct basic_timed_mutex
+ {
+ BOOST_STATIC_CONSTANT(unsigned char,lock_flag_bit=31);
+ BOOST_STATIC_CONSTANT(unsigned char,event_set_flag_bit=30);
+ BOOST_STATIC_CONSTANT(long,lock_flag_value=1<<lock_flag_bit);
+ BOOST_STATIC_CONSTANT(long,event_set_flag_value=1<<event_set_flag_bit);
+ long active_count;
+ void* event;
+
+ void initialize()
+ {
+ active_count=0;
+ event=0;
+ }
+
+ void destroy()
+ {
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4312)
+#endif
+ void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event,0);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+ if(old_event)
+ {
+ win32::CloseHandle(old_event);
+ }
+ }
+
+
+ bool try_lock()
+ {
+ return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit);
+ }
+
+ void lock()
+ {
+ BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
+ }
+ bool timed_lock(::boost::system_time const& wait_until)
+ {
+ if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit))
+ {
+ return true;
+ }
+ long old_count=active_count;
+ for(;;)
+ {
+ long const new_count=(old_count&lock_flag_value)?(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)
+ {
+ break;
+ }
+ old_count=current;
+ }
+
+ if(old_count&lock_flag_value)
+ {
+ bool lock_acquired=false;
+ void* const sem=get_event();
+
+ do
+ {
+ if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until))!=0)
+ {
+ BOOST_INTERLOCKED_DECREMENT(&active_count);
+ return false;
+ }
+ old_count&=~lock_flag_value;
+ old_count|=event_set_flag_value;
+ for(;;)
+ {
+ long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value;
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
+ if(current==old_count)
+ {
+ break;
+ }
+ old_count=current;
+ }
+ lock_acquired=!(old_count&lock_flag_value);
+ }
+ 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));
+ }
+
+ void unlock()
+ {
+ long const offset=lock_flag_value;
+ long const old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,lock_flag_value);
+ if(!(old_count&event_set_flag_value) && (old_count>offset))
+ {
+ if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit))
+ {
+ win32::SetEvent(get_event());
+ }
+ }
+ }
+
+ private:
+ void* get_event()
+ {
+ void* current_event=::boost::detail::interlocked_read_acquire(&event);
+
+ if(!current_event)
+ {
+ void* const new_event=win32::create_anonymous_event(win32::auto_reset_event,win32::event_initially_reset);
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4311)
+#pragma warning(disable:4312)
+#endif
+ void* const old_event=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&event,new_event,0);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+ if(old_event!=0)
+ {
+ win32::CloseHandle(new_event);
+ return old_event;
+ }
+ else
+ {
+ return new_event;
+ }
+ }
+ return current_event;
+ }
+
+ };
+
+ }
+}
+
+#define BOOST_BASIC_TIMED_MUTEX_INITIALIZER {0}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp
new file mode 100644
index 0000000..6e676b4
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp
@@ -0,0 +1,418 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright 2007-8 Anthony Williams
+
+#include <boost/thread/mutex.hpp>
+#include "thread_primitives.hpp"
+#include <limits.h>
+#include <boost/assert.hpp>
+#include <algorithm>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/thread_time.hpp>
+#include "interlocked_read.hpp"
+#include <boost/thread/xtime.hpp>
+#include <vector>
+#include <boost/intrusive_ptr.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ class basic_cv_list_entry;
+ void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+ void intrusive_ptr_release(basic_cv_list_entry * p);
+
+ class basic_cv_list_entry
+ {
+ private:
+ detail::win32::handle_manager semaphore;
+ detail::win32::handle_manager wake_sem;
+ long waiters;
+ bool notified;
+ long references;
+
+ basic_cv_list_entry(basic_cv_list_entry&);
+ void operator=(basic_cv_list_entry&);
+
+ public:
+ 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()),
+ waiters(1),notified(false),references(0)
+ {}
+
+ static bool no_waiters(boost::intrusive_ptr<basic_cv_list_entry> const& entry)
+ {
+ return !detail::interlocked_read_acquire(&entry->waiters);
+ }
+
+ void add_waiter()
+ {
+ BOOST_INTERLOCKED_INCREMENT(&waiters);
+ }
+
+ void remove_waiter()
+ {
+ BOOST_INTERLOCKED_DECREMENT(&waiters);
+ }
+
+ void release(unsigned count_to_release)
+ {
+ notified=true;
+ detail::win32::ReleaseSemaphore(semaphore,count_to_release,0);
+ }
+
+ void release_waiters()
+ {
+ release(detail::interlocked_read_acquire(&waiters));
+ }
+
+ bool is_notified() const
+ {
+ return notified;
+ }
+
+ bool wait(timeout wait_until)
+ {
+ return this_thread::interruptible_wait(semaphore,wait_until);
+ }
+
+ bool woken()
+ {
+ unsigned long const woken_result=detail::win32::WaitForSingleObject(wake_sem,0);
+ BOOST_ASSERT((woken_result==detail::win32::timeout) || (woken_result==0));
+ return woken_result==0;
+ }
+
+ friend void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+ friend void intrusive_ptr_release(basic_cv_list_entry * p);
+ };
+
+ inline void intrusive_ptr_add_ref(basic_cv_list_entry * p)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&p->references);
+ }
+
+ inline void intrusive_ptr_release(basic_cv_list_entry * p)
+ {
+ if(!BOOST_INTERLOCKED_DECREMENT(&p->references))
+ {
+ delete p;
+ }
+ }
+
+ class basic_condition_variable
+ {
+ boost::mutex internal_mutex;
+ long total_count;
+ unsigned active_generation_count;
+
+ typedef basic_cv_list_entry list_entry;
+
+ typedef boost::intrusive_ptr<list_entry> entry_ptr;
+ typedef std::vector<entry_ptr> generation_list;
+
+ generation_list generations;
+ detail::win32::handle_manager wake_sem;
+
+ void wake_waiters(long count_to_wake)
+ {
+ detail::interlocked_write_release(&total_count,total_count-count_to_wake);
+ detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);
+ }
+
+ template<typename lock_type>
+ struct relocker
+ {
+ lock_type& lock;
+ bool unlocked;
+
+ relocker(lock_type& lock_):
+ lock(lock_),unlocked(false)
+ {}
+ void unlock()
+ {
+ lock.unlock();
+ unlocked=true;
+ }
+ ~relocker()
+ {
+ if(unlocked)
+ {
+ lock.lock();
+ }
+
+ }
+ private:
+ relocker(relocker&);
+ void operator=(relocker&);
+ };
+
+
+ entry_ptr get_wait_entry()
+ {
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+
+ if(!wake_sem)
+ {
+ wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ BOOST_ASSERT(wake_sem);
+ }
+
+ detail::interlocked_write_release(&total_count,total_count+1);
+ if(generations.empty() || generations.back()->is_notified())
+ {
+ entry_ptr new_entry(new list_entry(wake_sem));
+ generations.push_back(new_entry);
+ return new_entry;
+ }
+ else
+ {
+ generations.back()->add_waiter();
+ return generations.back();
+ }
+ }
+
+ struct entry_manager
+ {
+ entry_ptr const entry;
+
+ entry_manager(entry_ptr const& entry_):
+ entry(entry_)
+ {}
+
+ ~entry_manager()
+ {
+ entry->remove_waiter();
+ }
+
+ list_entry* operator->()
+ {
+ 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)
+ {
+ relocker<lock_type> locker(lock);
+
+ entry_manager entry(get_wait_entry());
+
+ locker.unlock();
+
+ bool woken=false;
+ while(!woken)
+ {
+ if(!entry->wait(wait_until))
+ {
+ return false;
+ }
+
+ woken=entry->woken();
+ }
+ return woken;
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred)
+ {
+ while (!pred())
+ {
+ if(!do_wait(m, wait_until))
+ return pred();
+ }
+ return true;
+ }
+
+ basic_condition_variable(const basic_condition_variable& other);
+ basic_condition_variable& operator=(const basic_condition_variable& other);
+
+ public:
+ basic_condition_variable():
+ total_count(0),active_generation_count(0),wake_sem(0)
+ {}
+
+ ~basic_condition_variable()
+ {}
+
+ void notify_one()
+ {
+ if(detail::interlocked_read_acquire(&total_count))
+ {
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+ if(!total_count)
+ {
+ return;
+ }
+ wake_waiters(1);
+
+ for(generation_list::iterator it=generations.begin(),
+ end=generations.end();
+ it!=end;++it)
+ {
+ (*it)->release(1);
+ }
+ generations.erase(std::remove_if(generations.begin(),generations.end(),&basic_cv_list_entry::no_waiters),generations.end());
+ }
+ }
+
+ void notify_all()
+ {
+ if(detail::interlocked_read_acquire(&total_count))
+ {
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+ if(!total_count)
+ {
+ return;
+ }
+ wake_waiters(total_count);
+ for(generation_list::iterator it=generations.begin(),
+ end=generations.end();
+ it!=end;++it)
+ {
+ (*it)->release_waiters();
+ }
+ generations.clear();
+ wake_sem=detail::win32::handle(0);
+ }
+ }
+
+ };
+ }
+
+ class condition_variable:
+ private detail::basic_condition_variable
+ {
+ private:
+ condition_variable(condition_variable&);
+ void operator=(condition_variable&);
+ public:
+ condition_variable()
+ {}
+
+ using detail::basic_condition_variable::notify_one;
+ using detail::basic_condition_variable::notify_all;
+
+ void wait(unique_lock<mutex>& m)
+ {
+ do_wait(m,detail::timeout::sentinel());
+ }
+
+ template<typename predicate_type>
+ void wait(unique_lock<mutex>& m,predicate_type pred)
+ {
+ while(!pred()) wait(m);
+ }
+
+
+ bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
+ {
+ return do_wait(m,wait_until);
+ }
+
+ bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until)
+ {
+ return do_wait(m,system_time(wait_until));
+ }
+ template<typename duration_type>
+ bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
+ {
+ return do_wait(m,wait_duration.total_milliseconds());
+ }
+
+ template<typename predicate_type>
+ bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)
+ {
+ return do_wait(m,wait_until,pred);
+ }
+ template<typename predicate_type>
+ bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred)
+ {
+ return do_wait(m,system_time(wait_until),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);
+ }
+ };
+
+ class condition_variable_any:
+ private detail::basic_condition_variable
+ {
+ private:
+ condition_variable_any(condition_variable_any&);
+ void operator=(condition_variable_any&);
+ public:
+ condition_variable_any()
+ {}
+
+ using detail::basic_condition_variable::notify_one;
+ using detail::basic_condition_variable::notify_all;
+
+ template<typename lock_type>
+ void wait(lock_type& m)
+ {
+ do_wait(m,detail::timeout::sentinel());
+ }
+
+ template<typename lock_type,typename predicate_type>
+ void wait(lock_type& m,predicate_type pred)
+ {
+ while(!pred()) wait(m);
+ }
+
+ template<typename lock_type>
+ bool timed_wait(lock_type& m,boost::system_time const& wait_until)
+ {
+ return do_wait(m,wait_until);
+ }
+
+ template<typename lock_type>
+ bool timed_wait(lock_type& m,boost::xtime const& wait_until)
+ {
+ return do_wait(m,system_time(wait_until));
+ }
+
+ template<typename lock_type,typename duration_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration)
+ {
+ return do_wait(m,wait_duration.total_milliseconds());
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
+ {
+ return do_wait(m,wait_until,pred);
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred)
+ {
+ return do_wait(m,system_time(wait_until),pred);
+ }
+
+ 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);
+ }
+ };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp b/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp
new file mode 100644
index 0000000..133fb6f
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp
@@ -0,0 +1,80 @@
+#ifndef BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
+#define BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
+
+// interlocked_read_win32.hpp
+//
+// (C) Copyright 2005-8 Anthony Williams
+//
+// 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/detail/interlocked.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#ifdef BOOST_MSVC
+
+extern "C" void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+
+namespace boost
+{
+ namespace detail
+ {
+ inline long interlocked_read_acquire(long volatile* x)
+ {
+ long const res=*x;
+ _ReadWriteBarrier();
+ return res;
+ }
+ inline void* interlocked_read_acquire(void* volatile* x)
+ {
+ void* const res=*x;
+ _ReadWriteBarrier();
+ return res;
+ }
+
+ inline void interlocked_write_release(long volatile* x,long value)
+ {
+ _ReadWriteBarrier();
+ *x=value;
+ }
+ inline void interlocked_write_release(void* volatile* x,void* value)
+ {
+ _ReadWriteBarrier();
+ *x=value;
+ }
+ }
+}
+
+#else
+
+namespace boost
+{
+ namespace detail
+ {
+ inline long interlocked_read_acquire(long volatile* x)
+ {
+ return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0);
+ }
+ inline void* interlocked_read_acquire(void* volatile* x)
+ {
+ return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0);
+ }
+ inline void interlocked_write_release(long volatile* x,long value)
+ {
+ BOOST_INTERLOCKED_EXCHANGE(x,value);
+ }
+ inline void interlocked_write_release(void* volatile* x,void* value)
+ {
+ BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value);
+ }
+ }
+}
+
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp
new file mode 100644
index 0000000..efe6241
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp
@@ -0,0 +1,65 @@
+#ifndef BOOST_THREAD_WIN32_MUTEX_HPP
+#define BOOST_THREAD_WIN32_MUTEX_HPP
+// (C) Copyright 2005-7 Anthony Williams
+// 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 "basic_timed_mutex.hpp"
+#include <boost/utility.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/locks.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ typedef ::boost::detail::basic_timed_mutex underlying_mutex;
+ }
+
+ class mutex:
+ boost::noncopyable,
+ public ::boost::detail::underlying_mutex
+ {
+ public:
+ mutex()
+ {
+ initialize();
+ }
+ ~mutex()
+ {
+ destroy();
+ }
+
+ typedef unique_lock<mutex> scoped_lock;
+ typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
+ };
+
+ typedef mutex try_mutex;
+
+ class timed_mutex:
+ boost::noncopyable,
+ public ::boost::detail::basic_timed_mutex
+ {
+ public:
+ timed_mutex()
+ {
+ initialize();
+ }
+
+ ~timed_mutex()
+ {
+ destroy();
+ }
+
+ typedef unique_lock<timed_mutex> scoped_timed_lock;
+ typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
+ typedef scoped_timed_lock scoped_lock;
+ };
+}
+
+#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
new file mode 100644
index 0000000..a6fcc94
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/once.hpp
@@ -0,0 +1,136 @@
+#ifndef BOOST_THREAD_WIN32_ONCE_HPP
+#define BOOST_THREAD_WIN32_ONCE_HPP
+
+// once.hpp
+//
+// (C) Copyright 2005-7 Anthony Williams
+// (C) Copyright 2005 John Maddock
+//
+// 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/config/abi_prefix.hpp>
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std
+{
+ using ::memcpy;
+ using ::ptrdiff_t;
+}
+#endif
+
+namespace boost
+{
+ typedef long once_flag;
+
+#define BOOST_ONCE_INIT 0
+
+ namespace detail
+ {
+ struct win32_mutex_scoped_lock
+ {
+ void* const mutex_handle;
+ explicit win32_mutex_scoped_lock(void* mutex_handle_):
+ mutex_handle(mutex_handle_)
+ {
+ BOOST_VERIFY(!win32::WaitForSingleObject(mutex_handle,win32::infinite));
+ }
+ ~win32_mutex_scoped_lock()
+ {
+ BOOST_VERIFY(win32::ReleaseMutex(mutex_handle)!=0);
+ }
+ private:
+ void operator=(win32_mutex_scoped_lock&);
+ };
+
+#ifdef BOOST_NO_ANSI_APIS
+ template <class I>
+ void int_to_string(I p, wchar_t* buf)
+ {
+ for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
+ {
+ *buf = L'A' + static_cast<wchar_t>((p >> (i*4)) & 0x0f);
+ }
+ *buf = 0;
+ }
+#else
+ template <class I>
+ void int_to_string(I p, char* buf)
+ {
+ for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
+ {
+ *buf = 'A' + static_cast<char>((p >> (i*4)) & 0x0f);
+ }
+ *buf = 0;
+ }
+#endif
+
+ // create a named mutex. It doesn't really matter what this name is
+ // as long as it is unique both to this process, and to the address of "flag":
+ inline void* create_once_mutex(void* flag_address)
+ {
+
+#ifdef BOOST_NO_ANSI_APIS
+ typedef wchar_t char_type;
+ static const char_type fixed_mutex_name[]=L"{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
+#else
+ typedef char char_type;
+ static const char_type fixed_mutex_name[]="{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
+#endif
+ unsigned const once_mutex_name_fixed_buffer_size=sizeof(fixed_mutex_name)/sizeof(char_type);
+ unsigned const once_mutex_name_fixed_length=once_mutex_name_fixed_buffer_size-1;
+ unsigned const once_mutex_name_length=once_mutex_name_fixed_buffer_size+sizeof(void*)*2+sizeof(unsigned long)*2;
+ char_type mutex_name[once_mutex_name_length];
+
+ std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
+
+ BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(std::ptrdiff_t));
+ detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), mutex_name + once_mutex_name_fixed_length);
+ detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
+
+#ifdef BOOST_NO_ANSI_APIS
+ return win32::CreateMutexW(0, 0, mutex_name);
+#else
+ return win32::CreateMutexA(0, 0, mutex_name);
+#endif
+ }
+
+
+ }
+
+
+ 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;
+
+ if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value)
+ {
+ void* const mutex_handle(::boost::detail::create_once_mutex(&flag));
+ BOOST_ASSERT(mutex_handle);
+ detail::win32::handle_manager const closer(mutex_handle);
+ detail::win32_mutex_scoped_lock const lock(mutex_handle);
+
+ if(flag!=function_complete_flag_value)
+ {
+ f();
+ BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value);
+ }
+ }
+ }
+}
+
+#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
new file mode 100644
index 0000000..2360a92
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp
@@ -0,0 +1,64 @@
+#ifndef BOOST_RECURSIVE_MUTEX_WIN32_HPP
+#define BOOST_RECURSIVE_MUTEX_WIN32_HPP
+
+// recursive_mutex.hpp
+//
+// (C) Copyright 2006-7 Anthony Williams
+//
+// 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/utility.hpp>
+#include "basic_recursive_mutex.hpp"
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/locks.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class recursive_mutex:
+ boost::noncopyable,
+ public ::boost::detail::basic_recursive_mutex
+ {
+ public:
+ recursive_mutex()
+ {
+ ::boost::detail::basic_recursive_mutex::initialize();
+ }
+ ~recursive_mutex()
+ {
+ ::boost::detail::basic_recursive_mutex::destroy();
+ }
+
+ typedef unique_lock<recursive_mutex> scoped_lock;
+ typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
+ };
+
+ typedef recursive_mutex recursive_try_mutex;
+
+ class recursive_timed_mutex:
+ boost::noncopyable,
+ public ::boost::detail::basic_recursive_timed_mutex
+ {
+ public:
+ recursive_timed_mutex()
+ {
+ ::boost::detail::basic_recursive_timed_mutex::initialize();
+ }
+ ~recursive_timed_mutex()
+ {
+ ::boost::detail::basic_recursive_timed_mutex::destroy();
+ }
+
+ 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;
+ };
+}
+
+#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
new file mode 100644
index 0000000..58e8093
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp
@@ -0,0 +1,566 @@
+#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
+#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
+
+// (C) Copyright 2006-8 Anthony Williams
+//
+// 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/assert.hpp>
+#include <boost/detail/interlocked.hpp>
+#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>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class shared_mutex:
+ private boost::noncopyable
+ {
+ private:
+ struct state_data
+ {
+ unsigned shared_count:11,
+ shared_waiting:11,
+ exclusive:1,
+ upgrade:1,
+ exclusive_waiting:7,
+ exclusive_waiting_blocked:1;
+
+ friend bool operator==(state_data const& lhs,state_data const& rhs)
+ {
+ return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
+ }
+ };
+
+
+ template<typename T>
+ T interlocked_compare_exchange(T* target,T new_value,T comparand)
+ {
+ BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long));
+ long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
+ *reinterpret_cast<long*>(&new_value),
+ *reinterpret_cast<long*>(&comparand));
+ return *reinterpret_cast<T const*>(&res);
+ }
+
+ state_data state;
+ detail::win32::handle semaphores[2];
+ detail::win32::handle &unlock_sem;
+ detail::win32::handle &exclusive_sem;
+ detail::win32::handle upgrade_sem;
+
+ void release_waiters(state_data old_state)
+ {
+ if(old_state.exclusive_waiting)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(exclusive_sem,1,0)!=0);
+ }
+
+ if(old_state.shared_waiting || old_state.exclusive_waiting)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
+ }
+ }
+
+
+ public:
+ shared_mutex():
+ unlock_sem(semaphores[0]),
+ exclusive_sem(semaphores[1])
+ {
+ unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ state_data state_={0};
+ state=state_;
+ }
+
+ ~shared_mutex()
+ {
+ detail::win32::CloseHandle(upgrade_sem);
+ detail::win32::CloseHandle(unlock_sem);
+ detail::win32::CloseHandle(exclusive_sem);
+ }
+
+ bool try_lock_shared()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
+ {
+ ++new_state.shared_count;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
+ }
+
+ void lock_shared()
+ {
+ BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
+ }
+
+ 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(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+ {
+ ++new_state.shared_waiting;
+ }
+ else
+ {
+ ++new_state.shared_count;
+ }
+
+ 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;
+ }
+
+ unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until));
+ 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;
+ }
+
+ 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);
+ }
+ }
+
+ void unlock_shared()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ bool const last_reader=!--new_state.shared_count;
+
+ if(last_reader)
+ {
+ if(new_state.upgrade)
+ {
+ new_state.upgrade=false;
+ new_state.exclusive=true;
+ }
+ else
+ {
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+ }
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ if(last_reader)
+ {
+ if(old_state.upgrade)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0);
+ }
+ else
+ {
+ release_waiters(old_state);
+ }
+ }
+ break;
+ }
+ old_state=current_state;
+ }
+ }
+
+ void lock()
+ {
+ BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+
+ bool try_lock()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.shared_count || new_state.exclusive)
+ {
+ return false;
+ }
+ else
+ {
+ new_state.exclusive=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ return true;
+ }
+
+
+ bool timed_lock(boost::system_time const& wait_until)
+ {
+ 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;
+ 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;
+ }
+ unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,true,::boost::detail::get_milliseconds_until(wait_until));
+ 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);
+ }
+ }
+
+ void unlock()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.exclusive=false;
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ release_waiters(old_state);
+ }
+
+ void lock_upgrade()
+ {
+ for(;;)
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
+ {
+ ++new_state.shared_waiting;
+ }
+ else
+ {
+ ++new_state.shared_count;
+ new_state.upgrade=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade))
+ {
+ return;
+ }
+
+ BOOST_VERIFY(!detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite));
+ }
+ }
+
+ bool try_lock_upgrade()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
+ {
+ return false;
+ }
+ else
+ {
+ ++new_state.shared_count;
+ new_state.upgrade=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ return true;
+ }
+
+ void unlock_upgrade()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.upgrade=false;
+ bool const last_reader=!--new_state.shared_count;
+
+ if(last_reader)
+ {
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+ }
+
+ 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);
+ }
+ break;
+ }
+ old_state=current_state;
+ }
+ }
+
+ void unlock_upgrade_and_lock()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ bool const last_reader=!--new_state.shared_count;
+
+ if(last_reader)
+ {
+ new_state.upgrade=false;
+ new_state.exclusive=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ if(!last_reader)
+ {
+ BOOST_VERIFY(!detail::win32::WaitForSingleObject(upgrade_sem,detail::win32::infinite));
+ }
+ break;
+ }
+ old_state=current_state;
+ }
+ }
+
+ void unlock_and_lock_upgrade()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.exclusive=false;
+ new_state.upgrade=true;
+ ++new_state.shared_count;
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ release_waiters(old_state);
+ }
+
+ void unlock_and_lock_shared()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.exclusive=false;
+ ++new_state.shared_count;
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ release_waiters(old_state);
+ }
+
+ void unlock_upgrade_and_lock_shared()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.upgrade=false;
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ release_waiters(old_state);
+ }
+
+ };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp
new file mode 100644
index 0000000..1a6a1e0
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp
@@ -0,0 +1,178 @@
+#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+#define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright 2008 Anthony Williams
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/thread/thread_time.hpp>
+#include "thread_primitives.hpp"
+#include "thread_heap_alloc.hpp"
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ struct thread_exit_callback_node;
+ struct tss_data_node;
+
+ struct thread_data_base;
+ void intrusive_ptr_add_ref(thread_data_base * p);
+ void intrusive_ptr_release(thread_data_base * p);
+
+ struct 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;
+ boost::detail::tss_data_node* tss_data;
+ bool interruption_enabled;
+ unsigned id;
+
+ 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(0),
+ interruption_enabled(true),
+ id(0)
+ {}
+ virtual ~thread_data_base()
+ {}
+
+ friend void intrusive_ptr_add_ref(thread_data_base * p)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&p->count);
+ }
+
+ friend void intrusive_ptr_release(thread_data_base * p)
+ {
+ if(!BOOST_INTERLOCKED_DECREMENT(&p->count))
+ {
+ detail::heap_delete(p);
+ }
+ }
+
+ void interrupt()
+ {
+ BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);
+ }
+
+ typedef detail::win32::handle native_handle_type;
+
+ virtual void run()=0;
+ };
+
+ typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
+
+ struct timeout
+ {
+ unsigned long 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()),
+ milliseconds(milliseconds_),
+ relative(true),
+ abs_time(boost::get_system_time())
+ {}
+
+ timeout(boost::system_time const& abs_time_):
+ start(win32::GetTickCount()),
+ milliseconds(0),
+ relative(false),
+ abs_time(abs_time_)
+ {}
+
+ struct remaining_time
+ {
+ bool more;
+ unsigned long milliseconds;
+
+ remaining_time(uintmax_t remaining):
+ more(remaining>max_non_infinite_wait),
+ milliseconds(more?max_non_infinite_wait:(unsigned long)remaining)
+ {}
+ };
+
+ remaining_time remaining_milliseconds() const
+ {
+ if(is_sentinel())
+ {
+ return remaining_time(win32::infinite);
+ }
+ else if(relative)
+ {
+ unsigned long const now=win32::GetTickCount();
+ unsigned long const elapsed=now-start;
+ return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0);
+ }
+ else
+ {
+ system_time const now=get_system_time();
+ if(abs_time<=now)
+ {
+ return remaining_time(0);
+ }
+ return remaining_time((abs_time-now).total_milliseconds()+1);
+ }
+ }
+
+ bool is_sentinel() const
+ {
+ return milliseconds==~uintmax_t(0);
+ }
+
+
+ static timeout sentinel()
+ {
+ return timeout(sentinel_type());
+ }
+ private:
+ struct sentinel_type
+ {};
+
+ explicit timeout(sentinel_type):
+ start(0),milliseconds(~uintmax_t(0)),relative(true)
+ {}
+ };
+ }
+
+ namespace this_thread
+ {
+ void BOOST_THREAD_DECL yield();
+
+ bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
+ inline void interruptible_wait(unsigned long milliseconds)
+ {
+ interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
+ }
+ inline void interruptible_wait(system_time const& abs_time)
+ {
+ interruptible_wait(detail::win32::invalid_handle_value,abs_time);
+ }
+
+ template<typename TimeDuration>
+ inline void sleep(TimeDuration const& rel_time)
+ {
+ interruptible_wait(static_cast<unsigned long>(rel_time.total_milliseconds()));
+ }
+ inline void sleep(system_time const& abs_time)
+ {
+ interruptible_wait(abs_time);
+ }
+ }
+
+}
+
+#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
new file mode 100644
index 0000000..9f8186f
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp
@@ -0,0 +1,397 @@
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright 2007 Anthony Williams
+#ifndef THREAD_HEAP_ALLOC_HPP
+#define THREAD_HEAP_ALLOC_HPP
+#include <new>
+#include "thread_primitives.hpp"
+#include <stdexcept>
+#include <boost/assert.hpp>
+
+#if defined( BOOST_USE_WINDOWS_H )
+# include <windows.h>
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ using ::GetProcessHeap;
+ using ::HeapAlloc;
+ using ::HeapFree;
+ }
+ }
+}
+
+#else
+
+# ifdef HeapAlloc
+# undef HeapAlloc
+# endif
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ extern "C"
+ {
+ __declspec(dllimport) handle __stdcall GetProcessHeap();
+ __declspec(dllimport) void* __stdcall HeapAlloc(handle,unsigned long,ulong_ptr);
+ __declspec(dllimport) int __stdcall HeapFree(handle,unsigned long,void*);
+ }
+ }
+ }
+}
+
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ inline BOOST_THREAD_DECL void* allocate_raw_heap_memory(unsigned size)
+ {
+ void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size);
+ if(!heap_memory)
+ {
+ throw std::bad_alloc();
+ }
+ return heap_memory;
+ }
+
+ inline BOOST_THREAD_DECL void free_raw_heap_memory(void* heap_memory)
+ {
+ BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0);
+ }
+
+ template<typename T>
+ inline T* heap_new()
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ try
+ {
+ T* const data=new (heap_memory) T();
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+
+#ifdef BOOST_HAS_RVALUE_REFS
+ template<typename T,typename A1>
+ inline T* heap_new(A1&& a1)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ try
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+ 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
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+ 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
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+ static_cast<A3&&>(a3));
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+ 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
+ {
+ 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(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+#else
+ template<typename T,typename A1>
+ inline T* heap_new_impl(A1 a1)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ try
+ {
+ T* const data=new (heap_memory) T(a1);
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+
+ 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
+ {
+ T* const data=new (heap_memory) T(a1,a2);
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+
+ 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
+ {
+ T* const data=new (heap_memory) T(a1,a2,a3);
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+
+ 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
+ {
+ T* const data=new (heap_memory) T(a1,a2,a3,a4);
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+
+
+ template<typename T,typename A1>
+ inline T* heap_new(A1 const& a1)
+ {
+ return heap_new_impl<T,A1 const&>(a1);
+ }
+ template<typename T,typename A1>
+ inline T* heap_new(A1& a1)
+ {
+ return heap_new_impl<T,A1&>(a1);
+ }
+
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1&,A2&>(a1,a2);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
+
+#endif
+ template<typename T>
+ inline void heap_delete(T* data)
+ {
+ data->~T();
+ free_raw_heap_memory(data);
+ }
+
+ template<typename T>
+ struct do_heap_delete
+ {
+ void operator()(T* data) const
+ {
+ detail::heap_delete(data);
+ }
+ };
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+
+#endif
diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp
new file mode 100644
index 0000000..67a1bc3
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp
@@ -0,0 +1,398 @@
+#ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP
+#define BOOST_WIN32_THREAD_PRIMITIVES_HPP
+
+// win32_thread_primitives.hpp
+//
+// (C) Copyright 2005-7 Anthony Williams
+// (C) Copyright 2007 David Deakins
+//
+// 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/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/detail/interlocked.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;
+
+# ifdef BOOST_NO_ANSI_APIS
+ using ::CreateMutexW;
+ using ::CreateEventW;
+ using ::CreateSemaphoreW;
+# else
+ using ::CreateMutexA;
+ using ::CreateEventA;
+ using ::CreateSemaphoreA;
+# endif
+ using ::CloseHandle;
+ using ::ReleaseMutex;
+ using ::ReleaseSemaphore;
+ using ::SetEvent;
+ using ::ResetEvent;
+ using ::WaitForMultipleObjects;
+ using ::WaitForSingleObject;
+ using ::GetCurrentProcessId;
+ using ::GetCurrentThreadId;
+ using ::GetCurrentThread;
+ using ::GetCurrentProcess;
+ using ::DuplicateHandle;
+ using ::SleepEx;
+ using ::Sleep;
+ using ::QueueUserAPC;
+ using ::GetTickCount;
+ }
+ }
+}
+#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
+
+# ifdef UNDER_CE
+# ifndef WINAPI
+# ifndef _WIN32_WCE_EMULATION
+# define WINAPI __cdecl // Note this doesn't match the desktop definition
+# else
+# define WINAPI __stdcall
+# endif
+# endif
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+typedef int BOOL;
+typedef unsigned long DWORD;
+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);
+
+ extern "C"
+ {
+ struct _SECURITY_ATTRIBUTES;
+# ifdef BOOST_NO_ANSI_APIS
+ __declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
+ __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
+ __declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
+# else
+ __declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
+ __declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
+ __declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
+# endif
+ __declspec(dllimport) int __stdcall CloseHandle(void*);
+ __declspec(dllimport) int __stdcall ReleaseMutex(void*);
+ __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void*,unsigned long);
+ __declspec(dllimport) unsigned long __stdcall WaitForMultipleObjects(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds);
+ __declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*);
+ __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*);
+ __declspec(dllimport) int __stdcall ResetEvent(void*);
+# else
+ using ::GetCurrentProcessId;
+ using ::GetCurrentThreadId;
+ using ::GetCurrentThread;
+ using ::GetCurrentProcess;
+ using ::SetEvent;
+ using ::ResetEvent;
+# endif
+ }
+ }
+ }
+}
+#else
+# error "Win32 functions not available"
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ enum event_type
+ {
+ auto_reset_event=false,
+ manual_reset_event=true
+ };
+
+ enum initial_event_state
+ {
+ event_initially_reset=false,
+ event_initially_set=true
+ };
+
+ inline handle create_anonymous_event(event_type type,initial_event_state state)
+ {
+#if !defined(BOOST_NO_ANSI_APIS)
+ handle const res=win32::CreateEventA(0,type,state,0);
+#else
+ handle const res=win32::CreateEventW(0,type,state,0);
+#endif
+ if(!res)
+ {
+ throw thread_resource_error();
+ }
+ return res;
+ }
+
+ inline handle create_anonymous_semaphore(long initial_count,long max_count)
+ {
+#if !defined(BOOST_NO_ANSI_APIS)
+ handle const res=CreateSemaphoreA(0,initial_count,max_count,0);
+#else
+ handle const res=CreateSemaphoreW(0,initial_count,max_count,0);
+#endif
+ if(!res)
+ {
+ throw thread_resource_error();
+ }
+ return res;
+ }
+
+ inline handle duplicate_handle(handle source)
+ {
+ handle const current_process=GetCurrentProcess();
+ long const same_access_flag=2;
+ handle new_handle=0;
+ bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
+ if(!success)
+ {
+ throw thread_resource_error();
+ }
+ return new_handle;
+ }
+
+ inline void release_semaphore(handle semaphore,long count)
+ {
+ BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
+ }
+
+ class handle_manager
+ {
+ private:
+ handle handle_to_manage;
+ handle_manager(handle_manager&);
+ handle_manager& operator=(handle_manager&);
+
+ void cleanup()
+ {
+ if(handle_to_manage && handle_to_manage!=invalid_handle_value)
+ {
+ BOOST_VERIFY(CloseHandle(handle_to_manage));
+ }
+ }
+
+ public:
+ explicit handle_manager(handle handle_to_manage_):
+ handle_to_manage(handle_to_manage_)
+ {}
+ handle_manager():
+ handle_to_manage(0)
+ {}
+
+ handle_manager& operator=(handle new_handle)
+ {
+ cleanup();
+ handle_to_manage=new_handle;
+ return *this;
+ }
+
+ operator handle() const
+ {
+ return handle_to_manage;
+ }
+
+ handle duplicate() const
+ {
+ return duplicate_handle(handle_to_manage);
+ }
+
+ void swap(handle_manager& other)
+ {
+ std::swap(handle_to_manage,other.handle_to_manage);
+ }
+
+ handle release()
+ {
+ handle const res=handle_to_manage;
+ handle_to_manage=0;
+ return res;
+ }
+
+ bool operator!() const
+ {
+ return !handle_to_manage;
+ }
+
+ ~handle_manager()
+ {
+ cleanup();
+ }
+ };
+
+ }
+ }
+}
+
+#if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE)
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+#if _MSC_VER==1400
+ extern "C" unsigned char _interlockedbittestandset(long *a,long b);
+ extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
+#else
+ extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
+ extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
+#endif
+
+#pragma intrinsic(_interlockedbittestandset)
+#pragma intrinsic(_interlockedbittestandreset)
+
+ inline bool interlocked_bit_test_and_set(long* x,long bit)
+ {
+ return _interlockedbittestandset(x,bit)!=0;
+ }
+
+ inline bool interlocked_bit_test_and_reset(long* x,long bit)
+ {
+ return _interlockedbittestandreset(x,bit)!=0;
+ }
+
+ }
+ }
+}
+#define BOOST_THREAD_BTS_DEFINED
+#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ inline bool interlocked_bit_test_and_set(long* x,long bit)
+ {
+ __asm {
+ mov eax,bit;
+ mov edx,x;
+ lock bts [edx],eax;
+ setc al;
+ };
+ }
+
+ inline bool interlocked_bit_test_and_reset(long* x,long bit)
+ {
+ __asm {
+ mov eax,bit;
+ mov edx,x;
+ lock btr [edx],eax;
+ setc al;
+ };
+ }
+
+ }
+ }
+}
+#define BOOST_THREAD_BTS_DEFINED
+#endif
+
+#ifndef BOOST_THREAD_BTS_DEFINED
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ inline bool interlocked_bit_test_and_set(long* x,long bit)
+ {
+ long const value=1<<bit;
+ long old=*x;
+ do
+ {
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
+ if(current==old)
+ {
+ break;
+ }
+ old=current;
+ }
+ while(true);
+ return (old&value)!=0;
+ }
+
+ inline bool interlocked_bit_test_and_reset(long* x,long bit)
+ {
+ long const value=1<<bit;
+ long old=*x;
+ do
+ {
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old);
+ if(current==old)
+ {
+ break;
+ }
+ old=current;
+ }
+ while(true);
+ return (old&value)!=0;
+ }
+ }
+ }
+}
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif