diff options
| author | Remko Tronçon <git@el-tramo.be> | 2010-03-28 15:46:49 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2010-03-28 15:46:49 (GMT) | 
| commit | f53a1ef582494458301b97bf6e546be52d7ff7e8 (patch) | |
| tree | 7571b5cbcbd8a8f1dd1c966c9045b6cb69f0e295 /3rdParty/Boost/src/boost/thread/win32 | |
| parent | 638345680d72ca6acaf123f2c8c1c391f696e371 (diff) | |
| download | swift-f53a1ef582494458301b97bf6e546be52d7ff7e8.zip swift-f53a1ef582494458301b97bf6e546be52d7ff7e8.tar.bz2 | |
Moving submodule contents back.
Diffstat (limited to '3rdParty/Boost/src/boost/thread/win32')
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 | 
 Swift
 Swift