⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shared_mutex.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
📖 第 1 页 / 共 2 页
字号:
#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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -