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:
@@ -79,6 +79,10 @@ exe migrateable
|
||||
: migrateable.cpp
|
||||
;
|
||||
|
||||
exe hosting_thread
|
||||
: hosting_thread.cpp
|
||||
;
|
||||
|
||||
#exe backtrace
|
||||
# : backtrace.cpp
|
||||
# ;
|
||||
|
||||
29
example/fiber/hosting_thread.cpp
Normal file
29
example/fiber/hosting_thread.cpp
Normal 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;
|
||||
}
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user