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) |