1088 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			1088 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| #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
 | |
| //  (C) Copyright 2011-2013 Vicente J. Botet Escriba
 | |
| //
 | |
| //  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/core/no_exceptions_support.hpp>
 | |
| #include <boost/thread/detail/move.hpp>
 | |
| #include <boost/thread/detail/invoke.hpp>
 | |
| 
 | |
| #include <boost/bind.hpp>
 | |
| 
 | |
| #include <boost/config/abi_prefix.hpp>
 | |
| 
 | |
| #ifdef BOOST_NO_STDC_NAMESPACE
 | |
| namespace std
 | |
| {
 | |
|     using ::memcpy;
 | |
|     using ::ptrdiff_t;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| namespace boost
 | |
| {
 | |
|   struct once_flag;
 | |
|   namespace detail
 | |
|   {
 | |
|   struct once_context;
 | |
| 
 | |
|   inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
 | |
|   inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
 | |
|   inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
 | |
|   }
 | |
| 
 | |
| #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
 | |
| 
 | |
|   struct once_flag
 | |
|   {
 | |
|       BOOST_THREAD_NO_COPYABLE(once_flag)
 | |
|       BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
 | |
|         : status(0), count(0)
 | |
|       {}
 | |
|       long status;
 | |
|       long count;
 | |
|   private:
 | |
|       friend inline bool enter_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
 | |
|       friend inline void commit_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
 | |
|       friend inline void rollback_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
 | |
|   };
 | |
| 
 | |
| #define BOOST_ONCE_INIT once_flag()
 | |
| #else // BOOST_THREAD_PROVIDES_ONCE_CXX11
 | |
| 
 | |
|     struct once_flag
 | |
|     {
 | |
|         long status;
 | |
|         long count;
 | |
|     };
 | |
| 
 | |
| #define BOOST_ONCE_INIT {0,0}
 | |
| #endif  // BOOST_THREAD_PROVIDES_ONCE_CXX11
 | |
| 
 | |
| #if defined BOOST_THREAD_PROVIDES_INVOKE
 | |
| #define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
 | |
| #define BOOST_THREAD_INVOKE_RET_VOID_CALL
 | |
| #elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
 | |
| #define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
 | |
| #define BOOST_THREAD_INVOKE_RET_VOID_CALL
 | |
| #else
 | |
| #define BOOST_THREAD_INVOKE_RET_VOID boost::bind
 | |
| #define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
 | |
| #endif
 | |
| 
 | |
|     namespace detail
 | |
|     {
 | |
| #ifdef BOOST_NO_ANSI_APIS
 | |
|         typedef wchar_t once_char_type;
 | |
| #else
 | |
|         typedef char once_char_type;
 | |
| #endif
 | |
|         unsigned const once_mutex_name_fixed_length=54;
 | |
|         unsigned const once_mutex_name_length=once_mutex_name_fixed_length+
 | |
|             sizeof(void*)*2+sizeof(unsigned long)*2+1;
 | |
| 
 | |
|         template <class I>
 | |
|         void int_to_string(I p, once_char_type* buf)
 | |
|         {
 | |
|             for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
 | |
|             {
 | |
| #ifdef BOOST_NO_ANSI_APIS
 | |
|                 once_char_type const a=L'A';
 | |
| #else
 | |
|                 once_char_type const a='A';
 | |
| #endif
 | |
|                 *buf = a + static_cast<once_char_type>((p >> (i*4)) & 0x0f);
 | |
|             }
 | |
|             *buf = 0;
 | |
|         }
 | |
| 
 | |
|         inline void name_once_mutex(once_char_type* mutex_name,void* flag_address)
 | |
|         {
 | |
| #ifdef BOOST_NO_ANSI_APIS
 | |
|             static const once_char_type fixed_mutex_name[]=L"Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
 | |
| #else
 | |
|             static const once_char_type fixed_mutex_name[]="Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
 | |
| #endif
 | |
|             BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) ==
 | |
|                                 (sizeof(once_char_type)*(once_mutex_name_fixed_length+1)));
 | |
| 
 | |
|             std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
 | |
|             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);
 | |
|         }
 | |
| 
 | |
|         inline void* open_once_event(once_char_type* mutex_name,void* flag_address)
 | |
|         {
 | |
|             if(!*mutex_name)
 | |
|             {
 | |
|                 name_once_mutex(mutex_name,flag_address);
 | |
|             }
 | |
| 
 | |
| #ifdef BOOST_NO_ANSI_APIS
 | |
|             return ::boost::detail::win32::OpenEventW(
 | |
| #else
 | |
|             return ::boost::detail::win32::OpenEventA(
 | |
| #endif
 | |
|                 ::boost::detail::win32::synchronize |
 | |
|                 ::boost::detail::win32::event_modify_state,
 | |
|                 false,
 | |
|                 mutex_name);
 | |
|         }
 | |
| 
 | |
|         inline void* create_once_event(once_char_type* mutex_name,void* flag_address)
 | |
|         {
 | |
|             if(!*mutex_name)
 | |
|             {
 | |
|                 name_once_mutex(mutex_name,flag_address);
 | |
|             }
 | |
|             
 | |
|             return ::boost::detail::win32::create_event(
 | |
|                 mutex_name, 
 | |
|                 ::boost::detail::win32::manual_reset_event,
 | |
|                 ::boost::detail::win32::event_initially_reset);
 | |
|         }
 | |
| 
 | |
|         struct once_context {
 | |
|           long const function_complete_flag_value;
 | |
|           long const running_value;
 | |
|           bool counted;
 | |
|           detail::win32::handle_manager event_handle;
 | |
|           detail::once_char_type mutex_name[once_mutex_name_length];
 | |
|           once_context() :
 | |
|             function_complete_flag_value(0xc15730e2),
 | |
|             running_value(0x7f0725e3),
 | |
|             counted(false)
 | |
|           {
 | |
|             mutex_name[0]=0;
 | |
|           }
 | |
|         };
 | |
|         enum once_action {try_, break_, continue_};
 | |
| 
 | |
|         inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
 | |
|         {
 | |
|           long status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,ctx.running_value,0);
 | |
|           if(!status)
 | |
|           {
 | |
|             if(!ctx.event_handle)
 | |
|             {
 | |
|                 ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag);
 | |
|             }
 | |
|             if(ctx.event_handle)
 | |
|             {
 | |
|                 ::boost::detail::win32::ResetEvent(ctx.event_handle);
 | |
|             }
 | |
|             return true;
 | |
|           }
 | |
|           return false;
 | |
|         }
 | |
|         inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
 | |
|         {
 | |
|           if(!ctx.counted)
 | |
|           {
 | |
|               BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|               ctx.counted=true;
 | |
|           }
 | |
|           BOOST_INTERLOCKED_EXCHANGE(&flag.status,ctx.function_complete_flag_value);
 | |
|           if(!ctx.event_handle &&
 | |
|              (::boost::detail::interlocked_read_acquire(&flag.count)>1))
 | |
|           {
 | |
|               ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|           }
 | |
|           if(ctx.event_handle)
 | |
|           {
 | |
|               ::boost::detail::win32::SetEvent(ctx.event_handle);
 | |
|           }
 | |
|         }
 | |
|         inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
 | |
|         {
 | |
|           BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
 | |
|           if(!ctx.event_handle)
 | |
|           {
 | |
|               ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag);
 | |
|           }
 | |
|           if(ctx.event_handle)
 | |
|           {
 | |
|               ::boost::detail::win32::SetEvent(ctx.event_handle);
 | |
|           }
 | |
|         }
 | |
|     }
 | |
| 
 | |
| #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
 | |
| //#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
 | |
|     inline void call_once(once_flag& flag, void (*f)())
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   f();
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite, 0));
 | |
|         }
 | |
|     }
 | |
| //#endif
 | |
|     template<typename Function>
 | |
|     inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                     f();
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
|     template<typename Function, class A, class ...ArgTypes>
 | |
|     inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(A) a, BOOST_THREAD_RV_REF(ArgTypes)... args)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(
 | |
|                         thread_detail::decay_copy(boost::forward<Function>(f)),
 | |
|                         thread_detail::decay_copy(boost::forward<A>(a)),
 | |
|                         thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
 | |
|                   ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
| #else
 | |
| #if ! defined(BOOST_MSVC) && ! defined(BOOST_INTEL)
 | |
|     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:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                     f();
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
|     template<typename Function, typename T1>
 | |
|     void call_once(once_flag& flag,Function f, T1 p1)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
|     template<typename Function, typename T1, typename T2>
 | |
|     void call_once(once_flag& flag,Function f, T1 p1, T2 p2)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
|     template<typename Function, typename T1, typename T2, typename T3>
 | |
|     void call_once(once_flag& flag,Function f, T1 p1, T2 p2, T3 p3)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
| #elif defined BOOST_NO_CXX11_RVALUE_REFERENCES
 | |
| 
 | |
|     template<typename Function>
 | |
|     void call_once(once_flag& flag,Function const&f)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                     f();
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
|     template<typename Function, typename T1>
 | |
|     void call_once(once_flag& flag,Function const&f, T1 const&p1)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
|     template<typename Function, typename T1, typename T2>
 | |
|     void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
|     template<typename Function, typename T1, typename T2, typename T3>
 | |
|     void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2, T3 const&p3)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
| #endif
 | |
| #if 1
 | |
| #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
 | |
|         inline void call_once(once_flag& flag, void (*f)())
 | |
|         {
 | |
|             // Try for a quick win: if the procedure has already been called
 | |
|             // just skip through:
 | |
|             detail::once_context ctx;
 | |
|             while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|                   !=ctx.function_complete_flag_value)
 | |
|             {
 | |
|                 if(detail::enter_once_region(flag, ctx))
 | |
|                 {
 | |
|                     BOOST_TRY
 | |
|                     {
 | |
|                       f();
 | |
|                     }
 | |
|                     BOOST_CATCH(...)
 | |
|                     {
 | |
|                         detail::rollback_once_region(flag, ctx);
 | |
|                         BOOST_RETHROW
 | |
|                     }
 | |
|                     BOOST_CATCH_END
 | |
|                     detail::commit_once_region(flag, ctx);
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.counted)
 | |
|                 {
 | |
|                     BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                     ctx.counted=true;
 | |
|                     long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                     if(status==ctx.function_complete_flag_value)
 | |
|                     {
 | |
|                         break;
 | |
|                     }
 | |
|                     if(!ctx.event_handle)
 | |
|                     {
 | |
|                         ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                         continue;
 | |
|                     }
 | |
|                 }
 | |
|                 BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                                  ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|             }
 | |
|         }
 | |
|         template<typename T1>
 | |
|         void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1)), BOOST_THREAD_RV_REF(T1) p1)
 | |
|         {
 | |
|             // Try for a quick win: if the procedure has already been called
 | |
|             // just skip through:
 | |
|             detail::once_context ctx;
 | |
|             while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|                   !=ctx.function_complete_flag_value)
 | |
|             {
 | |
|                 if(detail::enter_once_region(flag, ctx))
 | |
|                 {
 | |
|                     BOOST_TRY
 | |
|                     {
 | |
|                        f(
 | |
|                            thread_detail::decay_copy(boost::forward<T1>(p1))
 | |
|                        );
 | |
|                     }
 | |
|                     BOOST_CATCH(...)
 | |
|                     {
 | |
|                         detail::rollback_once_region(flag, ctx);
 | |
|                         BOOST_RETHROW
 | |
|                     }
 | |
|                     BOOST_CATCH_END
 | |
|                     detail::commit_once_region(flag, ctx);
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.counted)
 | |
|                 {
 | |
|                     BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                     ctx.counted=true;
 | |
|                     long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                     if(status==ctx.function_complete_flag_value)
 | |
|                     {
 | |
|                         break;
 | |
|                     }
 | |
|                     if(!ctx.event_handle)
 | |
|                     {
 | |
|                         ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                         continue;
 | |
|                     }
 | |
|                 }
 | |
|                 BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                                  ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|             }
 | |
|         }
 | |
|         template<typename Function, typename T1, typename T2>
 | |
|         void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
 | |
|         {
 | |
|             // Try for a quick win: if the procedure has already been called
 | |
|             // just skip through:
 | |
|             detail::once_context ctx;
 | |
|             while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|                   !=ctx.function_complete_flag_value)
 | |
|             {
 | |
|                 if(detail::enter_once_region(flag, ctx))
 | |
|                 {
 | |
|                     BOOST_TRY
 | |
|                     {
 | |
|                       f(
 | |
|                           thread_detail::decay_copy(boost::forward<T1>(p1)),
 | |
|                           thread_detail::decay_copy(boost::forward<T2>(p2))
 | |
|                       );
 | |
|                     }
 | |
|                     BOOST_CATCH(...)
 | |
|                     {
 | |
|                         detail::rollback_once_region(flag, ctx);
 | |
|                         BOOST_RETHROW
 | |
|                     }
 | |
|                     BOOST_CATCH_END
 | |
|                     detail::commit_once_region(flag, ctx);
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.counted)
 | |
|                 {
 | |
|                     BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                     ctx.counted=true;
 | |
|                     long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                     if(status==ctx.function_complete_flag_value)
 | |
|                     {
 | |
|                         break;
 | |
|                     }
 | |
|                     if(!ctx.event_handle)
 | |
|                     {
 | |
|                         ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                         continue;
 | |
|                     }
 | |
|                 }
 | |
|                 BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                                  ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|             }
 | |
|         }
 | |
|         template<typename Function, typename T1, typename T2, typename T3>
 | |
|         void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
 | |
|         {
 | |
|             // Try for a quick win: if the procedure has already been called
 | |
|             // just skip through:
 | |
|             detail::once_context ctx;
 | |
|             while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|                   !=ctx.function_complete_flag_value)
 | |
|             {
 | |
|                 if(detail::enter_once_region(flag, ctx))
 | |
|                 {
 | |
|                     BOOST_TRY
 | |
|                     {
 | |
|                       f(
 | |
|                           thread_detail::decay_copy(boost::forward<T1>(p1)),
 | |
|                           thread_detail::decay_copy(boost::forward<T2>(p2)),
 | |
|                           thread_detail::decay_copy(boost::forward<T3>(p3))
 | |
|                       );
 | |
|                     }
 | |
|                     BOOST_CATCH(...)
 | |
|                     {
 | |
|                         detail::rollback_once_region(flag, ctx);
 | |
|                         BOOST_RETHROW
 | |
|                     }
 | |
|                     BOOST_CATCH_END
 | |
|                     detail::commit_once_region(flag, ctx);
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.counted)
 | |
|                 {
 | |
|                     BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                     ctx.counted=true;
 | |
|                     long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                     if(status==ctx.function_complete_flag_value)
 | |
|                     {
 | |
|                         break;
 | |
|                     }
 | |
|                     if(!ctx.event_handle)
 | |
|                     {
 | |
|                         ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                         continue;
 | |
|                     }
 | |
|                 }
 | |
|                 BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                                  ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|             }
 | |
|         }
 | |
| #endif
 | |
|     template<typename Function>
 | |
|     void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                     f();
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     template<typename Function, typename T1>
 | |
|     void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(
 | |
|                       thread_detail::decay_copy(boost::forward<Function>(f)),
 | |
|                       thread_detail::decay_copy(boost::forward<T1>(p1))
 | |
|                   ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
|     template<typename Function, typename T1, typename T2>
 | |
|     void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(
 | |
|                       thread_detail::decay_copy(boost::forward<Function>(f)),
 | |
|                       thread_detail::decay_copy(boost::forward<T1>(p1)),
 | |
|                       thread_detail::decay_copy(boost::forward<T2>(p2))
 | |
|                   ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
|     template<typename Function, typename T1, typename T2, typename T3>
 | |
|     void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
 | |
|     {
 | |
|         // Try for a quick win: if the procedure has already been called
 | |
|         // just skip through:
 | |
|         detail::once_context ctx;
 | |
|         while(::boost::detail::interlocked_read_acquire(&flag.status)
 | |
|               !=ctx.function_complete_flag_value)
 | |
|         {
 | |
|             if(detail::enter_once_region(flag, ctx))
 | |
|             {
 | |
|                 BOOST_TRY
 | |
|                 {
 | |
|                   BOOST_THREAD_INVOKE_RET_VOID(
 | |
|                       thread_detail::decay_copy(boost::forward<Function>(f)),
 | |
|                       thread_detail::decay_copy(boost::forward<T1>(p1)),
 | |
|                       thread_detail::decay_copy(boost::forward<T2>(p2)),
 | |
|                       thread_detail::decay_copy(boost::forward<T3>(p3))
 | |
|                   ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 | |
| 
 | |
|                 }
 | |
|                 BOOST_CATCH(...)
 | |
|                 {
 | |
|                     detail::rollback_once_region(flag, ctx);
 | |
|                     BOOST_RETHROW
 | |
|                 }
 | |
|                 BOOST_CATCH_END
 | |
|                 detail::commit_once_region(flag, ctx);
 | |
|                 break;
 | |
|             }
 | |
|             if(!ctx.counted)
 | |
|             {
 | |
|                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
 | |
|                 ctx.counted=true;
 | |
|                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
 | |
|                 if(status==ctx.function_complete_flag_value)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|                 if(!ctx.event_handle)
 | |
|                 {
 | |
|                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
 | |
|                     continue;
 | |
|                 }
 | |
|             }
 | |
|             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
 | |
|                              ctx.event_handle,::boost::detail::win32::infinite,0));
 | |
|         }
 | |
|     }
 | |
| 
 | |
| #endif
 | |
| #endif
 | |
| }
 | |
| 
 | |
| #include <boost/config/abi_suffix.hpp>
 | |
| 
 | |
| #endif
 | 
