2
0
mirror of https://github.com/boostorg/context.git synced 2026-01-19 04:02:17 +00:00

return thread-id of thread hosting the fiber (suspened)

This commit is contained in:
Oliver Kowalke
2018-03-23 08:31:21 +01:00
parent c52c9e6681
commit ce8d3ab779
4 changed files with 74 additions and 3 deletions

View File

@@ -79,6 +79,10 @@ exe migrateable
: migrateable.cpp
;
exe hosting_thread
: hosting_thread.cpp
;
#exe backtrace
# : backtrace.cpp
# ;

View File

@@ -0,0 +1,29 @@
// Copyright Oliver Kowalke 2016.
// 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)
#define UNW_LOCAL_ONLY
#include <cstdlib>
#include <iostream>
#include <thread>
#include <boost/context/fiber.hpp>
namespace ctx = boost::context;
int main() {
std::cout << "main-thread: " << std::this_thread::get_id() << std::endl;
ctx::fiber f{
[](ctx::fiber && m){
m = std::move( m).resume();
return std::move( m);
}};
std::cout << "hosting thread ID before resumption: " << f.previous_thread() << std::endl;
f = std::move( f).resume();
std::cout << "hosting thread ID after resumption: " << f.previous_thread() << std::endl;
std::cout << "main: done" << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -19,6 +19,7 @@
#include <functional>
#include <memory>
#include <ostream>
#include <thread>
#include <tuple>
#include <utility>
#include <variant>
@@ -60,11 +61,12 @@ namespace detail {
struct data {
enum flag_t {
flag_side_stack = 0
flag_side_stack = 0,
flag_hosting_thread
};
flag_t f;
std::variant< bool > v;
flag_t f;
std::variant< bool, std::thread::id > v;
};
inline
@@ -112,6 +114,8 @@ rep:
data * d = static_cast< data * >( t.data);
if ( data::flag_side_stack == d->f) {
d->v = fiber_uses_side_stack();
} else if ( data::flag_hosting_thread == d->f) {
d->v = std::thread::id{};
}
goto rep;
}
@@ -316,6 +320,7 @@ public:
fiber resume() && {
BOOST_ASSERT( nullptr != fctx_);
auto tid = std::this_thread::get_id();
rep:
auto t = detail::jump_fcontext(
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
@@ -328,6 +333,8 @@ rep:
detail::data * d = static_cast< detail::data * >( t.data);
if ( detail::data::flag_side_stack == d->f) {
d->v = detail::fiber_uses_side_stack();
} else if ( detail::data::flag_hosting_thread == d->f) {
d->v = tid;
}
fctx_ = t.fctx;
goto rep;
@@ -338,6 +345,7 @@ rep:
template< typename Fn >
fiber resume_with( Fn && fn) && {
BOOST_ASSERT( nullptr != fctx_);
auto tid = std::this_thread::get_id();
auto p = std::make_tuple( std::forward< Fn >( fn) );
auto t = detail::ontop_fcontext(
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
@@ -351,6 +359,8 @@ rep:
detail::data * d = static_cast< detail::data * >( t.data);
if ( detail::data::flag_side_stack == d->f) {
d->v = detail::fiber_uses_side_stack();
} else if ( detail::data::flag_hosting_thread == d->f) {
d->v = tid;
}
fctx_ = t.fctx;
t = detail::jump_fcontext(
@@ -378,6 +388,20 @@ rep:
return ! std::get< bool >( d.v);
}
std::thread::id previous_thread() {
BOOST_ASSERT( * this);
detail::data d = { detail::data::flag_hosting_thread };
auto t = detail::jump_fcontext(
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
detail::exchange( fctx_, nullptr),
#else
std::exchange( fctx_, nullptr),
#endif
& d);
fctx_ = t.fctx;
return std::get< std::thread::id >( d.v);
}
explicit operator bool() const noexcept {
return nullptr != fctx_;
}

View File

@@ -452,6 +452,19 @@ void test_use_system_stack() {
}
}
void test_hosting_thread() {
ctx::fiber f{
[](ctx::fiber && m){
m = std::move( m).resume();
return std::move( m);
}};
BOOST_CHECK( f);
BOOST_CHECK_EQUAL( std::thread::id{}, f.previous_thread() );
f = std::move( f).resume();
BOOST_CHECK_EQUAL( std::this_thread::get_id(), f.previous_thread() );
}
#ifdef BOOST_WINDOWS
void test_bug12215() {
ctx::fiber{
@@ -480,6 +493,7 @@ boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
test->add( BOOST_TEST_CASE( & test_sscanf) );
test->add( BOOST_TEST_CASE( & test_snprintf) );
test->add( BOOST_TEST_CASE( & test_use_system_stack) );
test->add( BOOST_TEST_CASE( & test_hosting_thread) );
#ifdef BOOST_WINDOWS
test->add( BOOST_TEST_CASE( & test_bug12215) );
#endif