Ticket #8943: intel_thread_once.patch

File intel_thread_once.patch, 6.9 KB (added by avrarov@…, 9 years ago)

Proposed solution. Tested with all listed above compilers.

  • boost/thread/win32/once.hpp

     
    363363        }
    364364    }
    365365#else
    366 #ifndef BOOST_MSVC
    367     template<typename Function>
    368     void call_once(once_flag& flag,Function f)
    369     {
    370         // Try for a quick win: if the procedure has already been called
    371         // just skip through:
    372         detail::once_context ctx;
    373         while(::boost::detail::interlocked_read_acquire(&flag.status)
    374               !=ctx.function_complete_flag_value)
    375         {
    376             if(detail::enter_once_region(flag, ctx))
    377             {
    378                 BOOST_TRY
    379                 {
    380                     f();
    381                 }
    382                 BOOST_CATCH(...)
    383                 {
    384                     detail::rollback_once_region(flag, ctx);
    385                     BOOST_RETHROW
    386                 }
    387                 BOOST_CATCH_END
    388                 detail::commit_once_region(flag, ctx);
    389                 break;
    390             }
    391             if(!ctx.counted)
    392             {
    393                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
    394                 ctx.counted=true;
    395                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
    396                 if(status==ctx.function_complete_flag_value)
    397                 {
    398                     break;
    399                 }
    400                 if(!ctx.event_handle)
    401                 {
    402                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
    403                     continue;
    404                 }
    405             }
    406             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
    407                              ctx.event_handle,::boost::detail::win32::infinite));
    408         }
    409     }
    410     template<typename Function, typename T1>
    411     void call_once(once_flag& flag,Function f, T1 p1)
    412     {
    413         // Try for a quick win: if the procedure has already been called
    414         // just skip through:
    415         detail::once_context ctx;
    416         while(::boost::detail::interlocked_read_acquire(&flag.status)
    417               !=ctx.function_complete_flag_value)
    418         {
    419             if(detail::enter_once_region(flag, ctx))
    420             {
    421                 BOOST_TRY
    422                 {
    423                   BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
    424                 }
    425                 BOOST_CATCH(...)
    426                 {
    427                     detail::rollback_once_region(flag, ctx);
    428                     BOOST_RETHROW
    429                 }
    430                 BOOST_CATCH_END
    431                 detail::commit_once_region(flag, ctx);
    432                 break;
    433             }
    434             if(!ctx.counted)
    435             {
    436                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
    437                 ctx.counted=true;
    438                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
    439                 if(status==ctx.function_complete_flag_value)
    440                 {
    441                     break;
    442                 }
    443                 if(!ctx.event_handle)
    444                 {
    445                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
    446                     continue;
    447                 }
    448             }
    449             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
    450                              ctx.event_handle,::boost::detail::win32::infinite));
    451         }
    452     }
    453     template<typename Function, typename T1, typename T2>
    454     void call_once(once_flag& flag,Function f, T1 p1, T2 p2)
    455     {
    456         // Try for a quick win: if the procedure has already been called
    457         // just skip through:
    458         detail::once_context ctx;
    459         while(::boost::detail::interlocked_read_acquire(&flag.status)
    460               !=ctx.function_complete_flag_value)
    461         {
    462             if(detail::enter_once_region(flag, ctx))
    463             {
    464                 BOOST_TRY
    465                 {
    466                   BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
    467                 }
    468                 BOOST_CATCH(...)
    469                 {
    470                     detail::rollback_once_region(flag, ctx);
    471                     BOOST_RETHROW
    472                 }
    473                 BOOST_CATCH_END
    474                 detail::commit_once_region(flag, ctx);
    475                 break;
    476             }
    477             if(!ctx.counted)
    478             {
    479                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
    480                 ctx.counted=true;
    481                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
    482                 if(status==ctx.function_complete_flag_value)
    483                 {
    484                     break;
    485                 }
    486                 if(!ctx.event_handle)
    487                 {
    488                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
    489                     continue;
    490                 }
    491             }
    492             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
    493                              ctx.event_handle,::boost::detail::win32::infinite));
    494         }
    495     }
    496     template<typename Function, typename T1, typename T2, typename T3>
    497     void call_once(once_flag& flag,Function f, T1 p1, T2 p2, T3 p3)
    498     {
    499         // Try for a quick win: if the procedure has already been called
    500         // just skip through:
    501         detail::once_context ctx;
    502         while(::boost::detail::interlocked_read_acquire(&flag.status)
    503               !=ctx.function_complete_flag_value)
    504         {
    505             if(detail::enter_once_region(flag, ctx))
    506             {
    507                 BOOST_TRY
    508                 {
    509                   BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
    510                 }
    511                 BOOST_CATCH(...)
    512                 {
    513                     detail::rollback_once_region(flag, ctx);
    514                     BOOST_RETHROW
    515                 }
    516                 BOOST_CATCH_END
    517                 detail::commit_once_region(flag, ctx);
    518                 break;
    519             }
    520             if(!ctx.counted)
    521             {
    522                 BOOST_INTERLOCKED_INCREMENT(&flag.count);
    523                 ctx.counted=true;
    524                 long status=::boost::detail::interlocked_read_acquire(&flag.status);
    525                 if(status==ctx.function_complete_flag_value)
    526                 {
    527                     break;
    528                 }
    529                 if(!ctx.event_handle)
    530                 {
    531                     ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
    532                     continue;
    533                 }
    534             }
    535             BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
    536                              ctx.event_handle,::boost::detail::win32::infinite));
    537         }
    538     }
    539 #elif defined BOOST_NO_CXX11_RVALUE_REFERENCES
     366#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    540367
    541368    template<typename Function>
    542369    void call_once(once_flag& flag,Function const&f)