#ifndef BOOST_WIN32_ONCE_HPP #define BOOST_WIN32_ONCE_HPP // once_atomic.hpp // // (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 namespace boost { typedef LONG volatile once_flag; #define BOOST_ONCE_INIT 0 namespace detail{ enum{ uninitialized = 0, initialized = 1, initializing = 2 }; } template void call_once(Function f,once_flag& flag) { bool exit = false; do{ switch(::InterlockedCompareExchange(&flag, detail::initializing, detail::uninitialized)) { case detail::initialized: // most likely situation, someone has been here before: exit = true; break; case detail::uninitialized: // we must call the proceedure: try{ f(); } catch(...) { // failure, reset to uninitiatized and throw: ::InterlockedExchange(&flag, detail::uninitialized); throw; } // success! ::InterlockedExchange(&flag, detail::initialized); exit = true; break; case detail::initializing: // race condition: ::Sleep(0); break; } }while(!exit); } } #endif