#ifndef BOOST_WIN32_ONCE_HPP #define BOOST_WIN32_ONCE_HPP // once.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 { struct once_flag { HANDLE semaphore_handle; ~once_flag() { ::CloseHandle(semaphore_handle); } }; #define BOOST_ONCE_INIT {0} namespace detail { std::string create_unique_name(void* p,const char* tag) { std::ostringstream res; res<<"unique-"< void call_once(Function f,once_flag& flag) { std::string const once_semaphore_name=detail::create_unique_name(&flag,"once_init"); LONG const max_semaphore_value=LONG_MAX; HANDLE const semaphore_handle(::CreateSemaphore(NULL,0,max_semaphore_value,once_semaphore_name.c_str())); if(!semaphore_handle) { abort(); } if(::GetLastError()==ERROR_ALREADY_EXISTS) { ::WaitForSingleObject(semaphore_handle,INFINITE); detail::semaphore_releaser releaser(semaphore_handle,1); ::CloseHandle(semaphore_handle); } else { flag.semaphore_handle=semaphore_handle; // leave handle to be cleaned up when flag destroyed detail::semaphore_releaser releaser(semaphore_handle,max_semaphore_value); f(); } } } #endif