#ifndef BOOST_WIN32_ONCE_CRITSEC_HPP #define BOOST_WIN32_ONCE_CRITSEC_HPP // once_critsec.hpp // // (C) Copyright 2005 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 #include #include #include namespace boost { typedef LONG once_flag; #define BOOST_ONCE_INIT {0} namespace detail { class critsec { public: critsec() { InitializeCriticalSection(&m_critsec); } ~critsec() { DeleteCriticalSection(&m_critsec); } void lock() { EnterCriticalSection(&m_critsec); } void unlock() { LeaveCriticalSection(&m_critsec); } private: CRITICAL_SECTION m_critsec; }; class scopedlock { public: scopedlock(critsec & lck) : m_lck(lck) { m_lck.lock(); } ~scopedlock() { m_lck.unlock(); } private: critsec & m_lck; }; } template void call_once(Function f,once_flag& flag) { static detail::critsec lck; detail::scopedlock guard(lck); if (!::InterlockedCompareExchange(&flag, 1, 1)) { f(); ::InterlockedExchange(&flag, 1); } } } #endif