diff --git a/boost/fiber/fiber.hpp b/boost/fiber/fiber.hpp index b569afd6..21ca87c2 100644 --- a/boost/fiber/fiber.hpp +++ b/boost/fiber/fiber.hpp @@ -317,7 +317,7 @@ public: } operator safe_bool() const BOOST_NOEXCEPT - { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } + { return ( ! empty() && ! impl_->is_complete() ) ? & dummy::nonnull : 0; } bool operator!() const BOOST_NOEXCEPT { return empty() || impl_->is_complete(); } diff --git a/boost/fiber/operations.hpp b/boost/fiber/operations.hpp index 5e136630..39b484da 100644 --- a/boost/fiber/operations.hpp +++ b/boost/fiber/operations.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -65,92 +66,28 @@ void yield_break() namespace fibers { -#ifndef BOOST_NO_RVALUE_REFERENCES -#ifdef BOOST_MSVC -#endif -#else -template< typename Fn > -fiber spawn( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = stack_allocator(), - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) -{ - fiber f( fn, attr, stack_alloc, alloc); - detail::scheduler::instance().spawn( f.impl_); - return f; -} - -template< typename Fn, typename StackAllocator > -fiber spawn( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) -{ - fiber f( fn, attr, stack_alloc, alloc); - detail::scheduler::instance().spawn( f.impl_); - return f; -} - -template< typename Fn, typename StackAllocator, typename Allocator > -fiber spawn( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc) -{ - fiber f( fn, attr, stack_alloc, alloc); - detail::scheduler::instance().spawn( f.impl_); - return f; -} - -template< typename Fn > -fiber spawn( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = stack_allocator(), - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) -{ - fiber f( fn, attr, stack_alloc, alloc); - detail::scheduler::instance().spawn( f.impl_); - return f; -} - -template< typename Fn, typename StackAllocator > -fiber spawn( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) -{ - fiber f( fn, attr, stack_alloc, alloc); - detail::scheduler::instance().spawn( f.impl_); - return f; -} - -template< typename Fn, typename StackAllocator, typename Allocator > -fiber spawn( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc) -{ - fiber f( fn, attr, stack_alloc, alloc); - detail::scheduler::instance().spawn( f.impl_); - return f; -} -#endif - inline bool run() { return detail::scheduler::instance().run(); } #define BOOST_FIBERS_WAITFOR_FIBER_FN_ARG(z,n,unused) \ - fiber & BOOST_PP_CAT(s,n) + fiber & BOOST_PP_CAT(f,n) #define BOOST_FIBERS_WAITFOR_FIBER_FN_ARGS(n) \ BOOST_PP_ENUM(n,BOOST_FIBERS_WAITFOR_FIBER_FN_ARG,~) #define BOOST_FIBERS_WAITFOR_FIBER_AND(z,n,t) \ - BOOST_PP_EXPR_IF(n,&&) BOOST_PP_CAT(s,n) + BOOST_PP_EXPR_IF(n,&&) BOOST_PP_CAT(f,n) #define BOOST_FIBERS_WAITFOR_FIBER_OR(z,n,t) \ - BOOST_PP_EXPR_IF(n,||) BOOST_PP_CAT(s,n) + BOOST_PP_EXPR_IF(n,||) BOOST_PP_CAT(f,n) #define BOOST_FIBERS_WAITFOR_FIBER_CANCEL(z,n,t) \ - if ( BOOST_PP_CAT(s,n) ) BOOST_PP_CAT(s,n).cancel(); + if ( BOOST_PP_CAT(f,n) ) BOOST_PP_CAT(f,n).cancel(); \ + else i = BOOST_PP_INC(n); #define BOOST_FIBERS_WAITFOR_FIBER_READY(z,n,t) \ - if ( ! BOOST_PP_CAT(s,n) ) return n; + if ( ! BOOST_PP_CAT(f,n) ) return BOOST_PP_INC(n); #define BOOST_FIBERS_WAITFOR_FIBER_ALL(z,n,unused) \ inline \ @@ -166,6 +103,7 @@ unsigned int waitfor_any( BOOST_FIBERS_WAITFOR_FIBER_FN_ARGS(n) ) \ { \ while ( BOOST_PP_REPEAT(n,BOOST_FIBERS_WAITFOR_FIBER_AND,~) ) \ run(); \ + BOOST_PP_REPEAT(n,BOOST_FIBERS_WAITFOR_FIBER_READY,~); \ return 0; \ } @@ -175,8 +113,9 @@ unsigned int waitfor_any_and_cancel( BOOST_FIBERS_WAITFOR_FIBER_FN_ARGS(n) ) \ { \ while ( BOOST_PP_REPEAT(n,BOOST_FIBERS_WAITFOR_FIBER_AND,~) ) \ run(); \ + unsigned int i = 0; \ BOOST_PP_REPEAT(n,BOOST_FIBERS_WAITFOR_FIBER_CANCEL,~); \ - return 0; \ + return i; \ } #ifndef BOOST_FIBERS_WAITFOR_FIBER_MAX_ARITY diff --git a/libs/fiber/test/test_waitfor.cpp b/libs/fiber/test/test_waitfor.cpp index 15f69c6b..4d6532aa 100644 --- a/libs/fiber/test/test_waitfor.cpp +++ b/libs/fiber/test/test_waitfor.cpp @@ -81,9 +81,10 @@ void test_waitfor_any() stm::fiber s2( boost::bind( f2, 5, boost::ref( v2) ) ); BOOST_CHECK( s1); BOOST_CHECK( s2); - stm::waitfor_any( s1, s2); + unsigned int i = stm::waitfor_any( s1, s2); BOOST_CHECK( ! s1); BOOST_CHECK( s2); + BOOST_CHECK_EQUAL( 1, i); BOOST_CHECK_EQUAL( 7, v1); BOOST_CHECK_EQUAL( 0, v2); } @@ -97,9 +98,10 @@ void test_waitfor_any_and_cancel() stm::fiber s2( boost::bind( f3, 5, boost::ref( v2) ) ); BOOST_CHECK( s1); BOOST_CHECK( s2); - stm::waitfor_any_and_cancel( s1, s2); + unsigned int i = stm::waitfor_any_and_cancel( s1, s2); BOOST_CHECK( ! s1); BOOST_CHECK( ! s2); + BOOST_CHECK_EQUAL( 1, i); BOOST_CHECK_EQUAL( 7, v1); BOOST_CHECK_EQUAL( 0, v2); }