2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-17 13:42:21 +00:00

fiber_context renamed to context

This commit is contained in:
Oliver Kowalke
2015-09-07 17:23:59 +02:00
parent 7f97616aa2
commit 6499bb07e7
41 changed files with 425 additions and 424 deletions

220
src/context.cpp Normal file
View File

@@ -0,0 +1,220 @@
// Copyright Oliver Kowalke 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/fiber/context.hpp"
#include "boost/fiber/algorithm.hpp"
#include "boost/fiber/exceptions.hpp"
#include "boost/fiber/fiber.hpp"
#include "boost/fiber/properties.hpp"
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
static context * main_fiber() {
static thread_local context mf;
static thread_local fiber_manager mgr;
mf.manager( & mgr);
return & mf;
}
thread_local context *
context::active_ = main_fiber();
context *
context::active() noexcept {
return active_;
}
context *
context::active( context * active) noexcept {
BOOST_ASSERT( nullptr != active);
context * old( active_);
active_ = active;
return old;
}
context::~context() {
BOOST_ASSERT( waiting_.empty() );
delete properties_;
}
void
context::release() {
BOOST_ASSERT( is_terminated() );
std::vector< context * > waiting;
// get all waiting fibers
splk_.lock();
waiting.swap( waiting_);
splk_.unlock();
// notify all waiting fibers
for ( context * f : waiting) {
BOOST_ASSERT( nullptr != f);
BOOST_ASSERT( ! f->is_terminated() );
f->set_ready();
}
// release fiber-specific-data
for ( fss_data_t::value_type & data : fss_data_) {
data.second.do_cleanup();
}
fss_data_.clear();
}
bool
context::join( context * f) {
BOOST_ASSERT( nullptr != f);
detail::spinlock_lock lk( splk_);
if ( is_terminated() ) {
return false;
}
waiting_.push_back( f);
return true;
}
void
context::interruption_blocked( bool blck) noexcept {
if ( blck) {
flags_ |= flag_interruption_blocked;
} else {
flags_ &= ~flag_interruption_blocked;
}
}
void
context::request_interruption( bool req) noexcept {
if ( req) {
flags_ |= flag_interruption_requested;
} else {
flags_ &= ~flag_interruption_requested;
}
}
void *
context::get_fss_data( void const * vp) const {
uintptr_t key( reinterpret_cast< uintptr_t >( vp) );
fss_data_t::const_iterator i( fss_data_.find( key) );
return fss_data_.end() != i ? i->second.vp : nullptr;
}
void
context::set_fss_data( void const * vp,
detail::fss_cleanup_function::ptr_t const& cleanup_fn,
void * data,
bool cleanup_existing) {
BOOST_ASSERT( cleanup_fn);
uintptr_t key( reinterpret_cast< uintptr_t >( vp) );
fss_data_t::iterator i( fss_data_.find( key) );
if ( fss_data_.end() != i) {
if( cleanup_existing) {
i->second.do_cleanup();
}
if ( nullptr != data) {
fss_data_.insert(
i,
std::make_pair(
key,
fss_data( data, cleanup_fn) ) );
} else {
fss_data_.erase( i);
}
} else {
fss_data_.insert(
std::make_pair(
key,
fss_data( data, cleanup_fn) ) );
}
}
void
context::set_properties( fiber_properties * props) {
delete properties_;
properties_ = props;
}
void
context::do_spawn( fiber const& f_) {
BOOST_ASSERT( nullptr != mgr_);
BOOST_ASSERT( this == active_);
context * f( f_.impl_.get() );
f->manager( mgr_);
mgr_->spawn( f);
}
void
context::do_schedule() {
BOOST_ASSERT( nullptr != mgr_);
BOOST_ASSERT( this == active_);
mgr_->run();
}
void
context::do_wait( detail::spinlock_lock & lk) {
BOOST_ASSERT( nullptr != mgr_);
BOOST_ASSERT( this == active_);
mgr_->wait( lk);
}
void
context::do_yield() {
BOOST_ASSERT( nullptr != mgr_);
BOOST_ASSERT( this == active_);
mgr_->yield();
}
void
context::do_join( context * f) {
BOOST_ASSERT( nullptr != mgr_);
BOOST_ASSERT( this == active_);
BOOST_ASSERT( nullptr != f);
mgr_->join( f);
}
std::size_t
context::do_ready_fibers() const noexcept {
BOOST_ASSERT( nullptr != mgr_);
BOOST_ASSERT( this == active_);
return mgr_->ready_fibers();
}
void
context::do_set_sched_algo( std::unique_ptr< sched_algorithm > algo) {
BOOST_ASSERT( nullptr != mgr_);
BOOST_ASSERT( this == active_);
mgr_->set_sched_algo( std::move( algo) );
}
std::chrono::steady_clock::duration
context::do_wait_interval() noexcept {
BOOST_ASSERT( nullptr != mgr_);
BOOST_ASSERT( this == active_);
return mgr_->wait_interval();
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif