Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:10:02

0001 #ifndef BOOST_THREAD_PTHREAD_ONCE_HPP
0002 #define BOOST_THREAD_PTHREAD_ONCE_HPP
0003 
0004 //  once.hpp
0005 //
0006 //  (C) Copyright 2007-8 Anthony Williams
0007 //  (C) Copyright 2011-2012 Vicente J. Botet Escriba
0008 //
0009 //  Distributed under the Boost Software License, Version 1.0. (See
0010 //  accompanying file LICENSE_1_0.txt or copy at
0011 //  http://www.boost.org/LICENSE_1_0.txt)
0012 
0013 #include <boost/thread/detail/config.hpp>
0014 #include <boost/thread/detail/move.hpp>
0015 #include <boost/thread/detail/invoke.hpp>
0016 
0017 #include <boost/thread/pthread/pthread_helpers.hpp>
0018 #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
0019 #include <boost/thread/detail/delete.hpp>
0020 #include <boost/core/no_exceptions_support.hpp>
0021 
0022 #include <boost/bind/bind.hpp>
0023 #include <boost/assert.hpp>
0024 #include <boost/config/abi_prefix.hpp>
0025 
0026 #include <boost/cstdint.hpp>
0027 #include <pthread.h>
0028 #include <csignal>
0029 
0030 namespace boost
0031 {
0032 
0033   struct once_flag;
0034 
0035   #define BOOST_ONCE_INITIAL_FLAG_VALUE 0
0036 
0037   namespace thread_detail
0038   {
0039     typedef boost::uint32_t  uintmax_atomic_t;
0040     #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##u
0041     #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(~0)
0042 
0043   }
0044 
0045 #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
0046 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0047     template<typename Function, class ...ArgTypes>
0048     inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
0049 #else
0050     template<typename Function>
0051     inline void call_once(once_flag& flag, Function f);
0052     template<typename Function, typename T1>
0053     inline void call_once(once_flag& flag, Function f, T1 p1);
0054     template<typename Function, typename T1, typename T2>
0055     inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
0056     template<typename Function, typename T1, typename T2, typename T3>
0057     inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
0058 #endif
0059 
0060   struct once_flag
0061   {
0062       BOOST_THREAD_NO_COPYABLE(once_flag)
0063       BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
0064         : epoch(BOOST_ONCE_INITIAL_FLAG_VALUE)
0065       {}
0066   private:
0067       volatile thread_detail::uintmax_atomic_t epoch;
0068 
0069 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0070       template<typename Function, class ...ArgTypes>
0071       friend void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
0072 #else
0073       template<typename Function>
0074       friend void call_once(once_flag& flag, Function f);
0075       template<typename Function, typename T1>
0076       friend void call_once(once_flag& flag, Function f, T1 p1);
0077       template<typename Function, typename T1, typename T2>
0078       friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
0079       template<typename Function, typename T1, typename T2, typename T3>
0080       friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
0081 
0082 #endif
0083 
0084   };
0085 
0086 #define BOOST_ONCE_INIT once_flag()
0087 
0088 #else // BOOST_THREAD_PROVIDES_ONCE_CXX11
0089 
0090     struct once_flag
0091     {
0092       volatile thread_detail::uintmax_atomic_t epoch;
0093     };
0094 
0095 #define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
0096 #endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
0097 
0098 
0099 #if defined BOOST_THREAD_PROVIDES_INVOKE
0100 #define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
0101 #define BOOST_THREAD_INVOKE_RET_VOID_CALL
0102 #elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
0103 #define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
0104 #define BOOST_THREAD_INVOKE_RET_VOID_CALL
0105 #else
0106 #define BOOST_THREAD_INVOKE_RET_VOID boost::bind
0107 #define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
0108 #endif
0109 
0110     namespace thread_detail
0111     {
0112         BOOST_THREAD_DECL uintmax_atomic_t& get_once_per_thread_epoch();
0113         BOOST_THREAD_DECL extern uintmax_atomic_t once_global_epoch;
0114         BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;
0115         BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;
0116     }
0117 
0118     // Based on Mike Burrows fast_pthread_once algorithm as described in
0119     // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html
0120 
0121 
0122 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0123 
0124 
0125   template<typename Function, class ...ArgTypes>
0126   inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
0127   {
0128     static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
0129     static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
0130     thread_detail::uintmax_atomic_t const epoch=flag.epoch;
0131     thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
0132 
0133     if(epoch<this_thread_epoch)
0134     {
0135         pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
0136 
0137         while(flag.epoch<=being_initialized)
0138         {
0139             if(flag.epoch==uninitialized_flag)
0140             {
0141                 flag.epoch=being_initialized;
0142                 BOOST_TRY
0143                 {
0144                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
0145                     BOOST_THREAD_INVOKE_RET_VOID(
0146                         thread_detail::decay_copy(boost::forward<Function>(f)),
0147                         thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
0148                     ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
0149                 }
0150                 BOOST_CATCH (...)
0151                 {
0152                     flag.epoch=uninitialized_flag;
0153                     BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0154                     BOOST_RETHROW
0155                 }
0156                 BOOST_CATCH_END
0157                 flag.epoch=--thread_detail::once_global_epoch;
0158                 BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0159             }
0160             else
0161             {
0162                 while(flag.epoch==being_initialized)
0163                 {
0164                     BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
0165                 }
0166             }
0167         }
0168         this_thread_epoch=thread_detail::once_global_epoch;
0169 
0170     }
0171   }
0172 #else
0173   template<typename Function>
0174   inline void call_once(once_flag& flag, Function f)
0175   {
0176     static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
0177     static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
0178     thread_detail::uintmax_atomic_t const epoch=flag.epoch;
0179     thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
0180 
0181     if(epoch<this_thread_epoch)
0182     {
0183         pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
0184 
0185         while(flag.epoch<=being_initialized)
0186         {
0187             if(flag.epoch==uninitialized_flag)
0188             {
0189                 flag.epoch=being_initialized;
0190                 BOOST_TRY
0191                 {
0192                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
0193                     f();
0194                 }
0195                 BOOST_CATCH (...)
0196                 {
0197                     flag.epoch=uninitialized_flag;
0198                     BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0199                     BOOST_RETHROW
0200                 }
0201                 BOOST_CATCH_END
0202                 flag.epoch=--thread_detail::once_global_epoch;
0203                 BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0204             }
0205             else
0206             {
0207                 while(flag.epoch==being_initialized)
0208                 {
0209                     BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
0210                 }
0211             }
0212         }
0213         this_thread_epoch=thread_detail::once_global_epoch;
0214     }
0215   }
0216 
0217   template<typename Function, typename T1>
0218   inline void call_once(once_flag& flag, Function f, T1 p1)
0219   {
0220     static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
0221     static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
0222     thread_detail::uintmax_atomic_t const epoch=flag.epoch;
0223     thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
0224 
0225     if(epoch<this_thread_epoch)
0226     {
0227         pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
0228 
0229         while(flag.epoch<=being_initialized)
0230         {
0231             if(flag.epoch==uninitialized_flag)
0232             {
0233                 flag.epoch=being_initialized;
0234                 BOOST_TRY
0235                 {
0236                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
0237                     BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
0238                 }
0239                 BOOST_CATCH (...)
0240                 {
0241                     flag.epoch=uninitialized_flag;
0242                     BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0243                     BOOST_RETHROW
0244                 }
0245                 BOOST_CATCH_END
0246                 flag.epoch=--thread_detail::once_global_epoch;
0247                 BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0248             }
0249             else
0250             {
0251                 while(flag.epoch==being_initialized)
0252                 {
0253                     BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
0254                 }
0255             }
0256         }
0257         this_thread_epoch=thread_detail::once_global_epoch;
0258     }
0259   }
0260   template<typename Function, typename T1, typename T2>
0261   inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2)
0262   {
0263     static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
0264     static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
0265     thread_detail::uintmax_atomic_t const epoch=flag.epoch;
0266     thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
0267 
0268     if(epoch<this_thread_epoch)
0269     {
0270         pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
0271 
0272         while(flag.epoch<=being_initialized)
0273         {
0274             if(flag.epoch==uninitialized_flag)
0275             {
0276                 flag.epoch=being_initialized;
0277                 BOOST_TRY
0278                 {
0279                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
0280                     BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
0281         }
0282                 BOOST_CATCH (...)
0283                 {
0284                     flag.epoch=uninitialized_flag;
0285                     BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0286                     BOOST_RETHROW
0287                 }
0288                 BOOST_CATCH_END
0289                 flag.epoch=--thread_detail::once_global_epoch;
0290                 BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0291             }
0292             else
0293             {
0294                 while(flag.epoch==being_initialized)
0295                 {
0296                     BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
0297                 }
0298             }
0299         }
0300         this_thread_epoch=thread_detail::once_global_epoch;
0301     }
0302   }
0303 
0304   template<typename Function, typename T1, typename T2, typename T3>
0305   inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3)
0306   {
0307     static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
0308     static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
0309     thread_detail::uintmax_atomic_t const epoch=flag.epoch;
0310     thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
0311 
0312     if(epoch<this_thread_epoch)
0313     {
0314         pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
0315 
0316         while(flag.epoch<=being_initialized)
0317         {
0318             if(flag.epoch==uninitialized_flag)
0319             {
0320                 flag.epoch=being_initialized;
0321                 BOOST_TRY
0322                 {
0323                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
0324                     BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2, p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
0325         }
0326                 BOOST_CATCH (...)
0327                 {
0328                     flag.epoch=uninitialized_flag;
0329                     BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0330                     BOOST_RETHROW
0331                 }
0332                 BOOST_CATCH_END
0333                 flag.epoch=--thread_detail::once_global_epoch;
0334                 BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0335             }
0336             else
0337             {
0338                 while(flag.epoch==being_initialized)
0339                 {
0340                     BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
0341                 }
0342             }
0343         }
0344         this_thread_epoch=thread_detail::once_global_epoch;
0345     }
0346   }
0347 
0348   template<typename Function>
0349   inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
0350   {
0351     static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
0352     static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
0353     thread_detail::uintmax_atomic_t const epoch=flag.epoch;
0354     thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
0355 
0356     if(epoch<this_thread_epoch)
0357     {
0358         pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
0359 
0360         while(flag.epoch<=being_initialized)
0361         {
0362             if(flag.epoch==uninitialized_flag)
0363             {
0364                 flag.epoch=being_initialized;
0365                 BOOST_TRY
0366                 {
0367                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
0368                     f();
0369                 }
0370                 BOOST_CATCH (...)
0371                 {
0372                     flag.epoch=uninitialized_flag;
0373                     BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0374                     BOOST_RETHROW
0375                 }
0376                 BOOST_CATCH_END
0377                 flag.epoch=--thread_detail::once_global_epoch;
0378                 BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0379             }
0380             else
0381             {
0382                 while(flag.epoch==being_initialized)
0383                 {
0384                     BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
0385                 }
0386             }
0387         }
0388         this_thread_epoch=thread_detail::once_global_epoch;
0389     }
0390   }
0391 
0392   template<typename Function, typename T1>
0393   inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
0394   {
0395     static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
0396     static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
0397     thread_detail::uintmax_atomic_t const epoch=flag.epoch;
0398     thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
0399 
0400     if(epoch<this_thread_epoch)
0401     {
0402         pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
0403 
0404         while(flag.epoch<=being_initialized)
0405         {
0406             if(flag.epoch==uninitialized_flag)
0407             {
0408                 flag.epoch=being_initialized;
0409                 BOOST_TRY
0410                 {
0411                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
0412                     BOOST_THREAD_INVOKE_RET_VOID(
0413                         thread_detail::decay_copy(boost::forward<Function>(f)),
0414                         thread_detail::decay_copy(boost::forward<T1>(p1))
0415                     ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
0416                 }
0417                 BOOST_CATCH (...)
0418                 {
0419                     flag.epoch=uninitialized_flag;
0420                     BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0421                     BOOST_RETHROW
0422                 }
0423                 BOOST_CATCH_END
0424                 flag.epoch=--thread_detail::once_global_epoch;
0425                 BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0426             }
0427             else
0428             {
0429                 while(flag.epoch==being_initialized)
0430                 {
0431                     BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
0432                 }
0433             }
0434         }
0435         this_thread_epoch=thread_detail::once_global_epoch;
0436     }
0437   }
0438   template<typename Function, typename T1, typename T2>
0439   inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
0440   {
0441     static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
0442     static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
0443     thread_detail::uintmax_atomic_t const epoch=flag.epoch;
0444     thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
0445 
0446     if(epoch<this_thread_epoch)
0447     {
0448         pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
0449 
0450         while(flag.epoch<=being_initialized)
0451         {
0452             if(flag.epoch==uninitialized_flag)
0453             {
0454                 flag.epoch=being_initialized;
0455                 BOOST_TRY
0456                 {
0457                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
0458                     BOOST_THREAD_INVOKE_RET_VOID(
0459                         thread_detail::decay_copy(boost::forward<Function>(f)),
0460                         thread_detail::decay_copy(boost::forward<T1>(p1)),
0461                         thread_detail::decay_copy(boost::forward<T1>(p2))
0462                     ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
0463                 }
0464                 BOOST_CATCH (...)
0465                 {
0466                     flag.epoch=uninitialized_flag;
0467                     BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0468                     BOOST_RETHROW
0469                 }
0470                 BOOST_CATCH_END
0471                 flag.epoch=--thread_detail::once_global_epoch;
0472                 BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0473             }
0474             else
0475             {
0476                 while(flag.epoch==being_initialized)
0477                 {
0478                     BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
0479                 }
0480             }
0481         }
0482         this_thread_epoch=thread_detail::once_global_epoch;
0483     }
0484   }
0485 
0486   template<typename Function, typename T1, typename T2, typename T3>
0487   inline 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)
0488   {
0489     static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
0490     static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
0491     thread_detail::uintmax_atomic_t const epoch=flag.epoch;
0492     thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
0493 
0494     if(epoch<this_thread_epoch)
0495     {
0496         pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
0497 
0498         while(flag.epoch<=being_initialized)
0499         {
0500             if(flag.epoch==uninitialized_flag)
0501             {
0502                 flag.epoch=being_initialized;
0503                 BOOST_TRY
0504                 {
0505                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
0506                     BOOST_THREAD_INVOKE_RET_VOID(
0507                         thread_detail::decay_copy(boost::forward<Function>(f)),
0508                         thread_detail::decay_copy(boost::forward<T1>(p1)),
0509                         thread_detail::decay_copy(boost::forward<T1>(p2)),
0510                         thread_detail::decay_copy(boost::forward<T1>(p3))
0511                     ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
0512                 }
0513                 BOOST_CATCH (...)
0514                 {
0515                     flag.epoch=uninitialized_flag;
0516                     BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0517                     BOOST_RETHROW
0518                 }
0519                 BOOST_CATCH_END
0520                 flag.epoch=--thread_detail::once_global_epoch;
0521                 BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
0522             }
0523             else
0524             {
0525                 while(flag.epoch==being_initialized)
0526                 {
0527                     BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
0528                 }
0529             }
0530         }
0531         this_thread_epoch=thread_detail::once_global_epoch;
0532     }
0533   }
0534 
0535 #endif
0536 
0537 }
0538 
0539 #include <boost/config/abi_suffix.hpp>
0540 
0541 #endif