1 2 // Copyright Oliver Kowalke 2013. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 #include "boost/fiber/fiber.hpp" 8 9 #include <system_error> 10 11 #include <boost/assert.hpp> 12 13 #include "boost/fiber/exceptions.hpp" 14 #include "boost/fiber/scheduler.hpp" 15 16 #ifdef BOOST_HAS_ABI_HEADERS 17 # include BOOST_ABI_PREFIX 18 #endif 19 20 namespace boost { 21 namespace fibers { 22 23 void start_()24fiber::start_() noexcept { 25 context * ctx = context::active(); 26 ctx->attach( impl_.get() ); 27 switch ( impl_->get_policy() ) { 28 case launch::post: 29 // push new fiber to ready-queue 30 // resume executing current fiber 31 ctx->get_scheduler()->schedule( impl_.get() ); 32 break; 33 case launch::dispatch: 34 // resume new fiber and push current fiber 35 // to ready-queue 36 impl_->resume( ctx); 37 break; 38 default: 39 BOOST_ASSERT_MSG( false, "unknown launch-policy"); 40 } 41 } 42 43 void join()44fiber::join() { 45 // FIXME: must fiber::join() be synchronized? 46 if ( BOOST_UNLIKELY( context::active()->get_id() == get_id() ) ) { 47 throw fiber_error{ std::make_error_code( std::errc::resource_deadlock_would_occur), 48 "boost fiber: trying to join itself" }; 49 } 50 if ( BOOST_UNLIKELY( ! joinable() ) ) { 51 throw fiber_error{ std::make_error_code( std::errc::invalid_argument), 52 "boost fiber: fiber not joinable" }; 53 } 54 impl_->join(); 55 impl_.reset(); 56 } 57 58 void detach()59fiber::detach() { 60 if ( BOOST_UNLIKELY( ! joinable() ) ) { 61 throw fiber_error{ std::make_error_code( std::errc::invalid_argument), 62 "boost fiber: fiber not joinable" }; 63 } 64 impl_.reset(); 65 } 66 67 }} 68 69 #ifdef BOOST_HAS_ABI_HEADERS 70 # include BOOST_ABI_SUFFIX 71 #endif 72