From 00ae711cd71c9163bdbcd5c3b972477b4d114592 Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Wed, 16 Sep 2015 22:11:11 +0200 Subject: [PATCH] join only non-terminated fibers - context::join() adds active-context to wait-queue only if joined context is not terminated - we can not use terminated_is_linked() because the context might already be removed from scheudler's termianted-queue --- include/boost/fiber/context.hpp | 3 ++- src/context.cpp | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/boost/fiber/context.hpp b/include/boost/fiber/context.hpp index 615cfd93..0773f6e2 100644 --- a/include/boost/fiber/context.hpp +++ b/include/boost/fiber/context.hpp @@ -101,7 +101,8 @@ private: enum flag_t { flag_main_context = 1 << 1, flag_dispatcher_context = 1 << 2, - flag_worker_context = 1 << 3 + flag_worker_context = 1 << 3, + flag_terminated = 1 << 4 }; static thread_local context * active_; diff --git a/src/context.cpp b/src/context.cpp index 59e32b5f..ecd2d7c3 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -44,6 +44,7 @@ context::active( context * active) noexcept { void context::set_terminated_() noexcept { + flags_ |= flag_terminated; scheduler_->set_terminated( this); } @@ -127,14 +128,17 @@ context::release() noexcept { void context::join() noexcept { - // get active context - context * active_ctx = context::active(); - // push active context to wait-queue, member - // of the context which has to be joined by - // the active context - wait_queue_.push_back( * active_ctx); - // suspend active context - scheduler_->re_schedule( active_ctx); + // wait for context which is not terminated + if ( 0 == ( flags_ & flag_terminated) ) { + // get active context + context * active_ctx = context::active(); + // push active context to wait-queue, member + // of the context which has to be joined by + // the active context + wait_queue_.push_back( * active_ctx); + // suspend active context + scheduler_->re_schedule( active_ctx); + } } bool