mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-17 13:42:21 +00:00
support sleep_for()/sleep_until()
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#define BOOST_FIBERS_CONTEXT_H
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
@@ -16,6 +17,7 @@
|
||||
#include <boost/context/stack_context.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive/parent_from_member.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
@@ -67,6 +69,14 @@ typedef intrusive::list_member_hook<
|
||||
>
|
||||
> ready_hook;
|
||||
|
||||
struct sleep_tag;
|
||||
typedef intrusive::set_member_hook<
|
||||
intrusive::tag< sleep_tag >,
|
||||
intrusive::link_mode<
|
||||
intrusive::auto_unlink
|
||||
>
|
||||
> sleep_hook;
|
||||
|
||||
struct terminated_tag;
|
||||
typedef intrusive::list_member_hook<
|
||||
intrusive::tag< terminated_tag >,
|
||||
@@ -88,9 +98,11 @@ constexpr worker_context_t worker_context = worker_context_t();
|
||||
|
||||
class BOOST_FIBERS_DECL context {
|
||||
public:
|
||||
detail::ready_hook ready_hook_;
|
||||
detail::terminated_hook terminated_hook_;
|
||||
detail::wait_hook wait_hook_;
|
||||
detail::ready_hook ready_hook_;
|
||||
detail::sleep_hook sleep_hook_;
|
||||
detail::terminated_hook terminated_hook_;
|
||||
detail::wait_hook wait_hook_;
|
||||
std::chrono::steady_clock::time_point tp_;
|
||||
|
||||
typedef intrusive::list<
|
||||
context,
|
||||
@@ -202,6 +214,7 @@ public:
|
||||
ready_hook_(),
|
||||
terminated_hook_(),
|
||||
wait_hook_(),
|
||||
tp_( (std::chrono::steady_clock::time_point::max)() ),
|
||||
use_count_( 1), // fiber instance or scheduler owner
|
||||
flags_( flag_worker_context),
|
||||
scheduler_( nullptr),
|
||||
@@ -238,6 +251,8 @@ public:
|
||||
|
||||
void yield() noexcept;
|
||||
|
||||
bool wait_until( std::chrono::steady_clock::time_point const&);
|
||||
|
||||
bool is_main_context() const noexcept {
|
||||
return 0 != ( flags_ & flag_main_context);
|
||||
}
|
||||
@@ -258,6 +273,8 @@ public:
|
||||
|
||||
bool ready_is_linked();
|
||||
|
||||
bool sleep_is_linked();
|
||||
|
||||
void wait_unlink();
|
||||
|
||||
friend void intrusive_ptr_add_ref( context * ctx) {
|
||||
|
||||
42
include/boost/fiber/detail/convert.hpp
Normal file
42
include/boost/fiber/detail/convert.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_FIBERS_DETAIL_CONVERT_H
|
||||
#define BOOST_FIBERS_DETAIL_CONVERT_H
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
# include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace fibers {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
std::chrono::steady_clock::time_point convert(
|
||||
std::chrono::steady_clock::time_point const& timeout_time) noexcept {
|
||||
return timeout_time;
|
||||
}
|
||||
|
||||
template< typename Clock, typename Duration >
|
||||
std::chrono::steady_clock::time_point convert(
|
||||
std::chrono::time_point< Clock, Duration > const& timeout_time) {
|
||||
return std::chrono::steady_clock::now() + ( timeout_time - Clock::now() );
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
# include BOOST_ABI_SUFFIX
|
||||
#endif
|
||||
|
||||
#endif // BOOST_FIBERS_DETAIL_CONVERT_H
|
||||
@@ -6,10 +6,13 @@
|
||||
#ifndef BOOST_THIS_FIBER_OPERATIONS_H
|
||||
#define BOOST_THIS_FIBER_OPERATIONS_H
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
#include <boost/fiber/context.hpp>
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
#include <boost/fiber/detail/convert.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
# include BOOST_ABI_PREFIX
|
||||
@@ -28,6 +31,23 @@ void yield() noexcept {
|
||||
fibers::context::active()->yield();
|
||||
}
|
||||
|
||||
template< typename Clock, typename Duration >
|
||||
void sleep_until( std::chrono::time_point< Clock, Duration > const& sleep_time_) {
|
||||
std::chrono::steady_clock::time_point sleep_time(
|
||||
boost::fibers::detail::convert( sleep_time_) );
|
||||
fibers::context::active()->wait_until( sleep_time);
|
||||
// TODO: check if fiber was interrupted
|
||||
//interruption_point();
|
||||
}
|
||||
|
||||
template< typename Rep, typename Period >
|
||||
void sleep_for( std::chrono::duration< Rep, Period > const& timeout_duration) {
|
||||
fibers::context::active()->wait_until(
|
||||
std::chrono::steady_clock::now() + timeout_duration);
|
||||
// TODO: check if fiber was interrupted
|
||||
//interruption_point();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
#ifndef BOOST_FIBERS_FIBER_MANAGER_H
|
||||
#define BOOST_FIBERS_FIBER_MANAGER_H
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
|
||||
#include <boost/fiber/context.hpp>
|
||||
#include <boost/fiber/detail/autoreset_event.hpp>
|
||||
@@ -23,20 +26,35 @@ namespace fibers {
|
||||
|
||||
class BOOST_FIBERS_DECL scheduler {
|
||||
private:
|
||||
struct timepoint_less {
|
||||
bool operator()( context const& l, context const& r) {
|
||||
return l.tp_ < r.tp_;
|
||||
}
|
||||
};
|
||||
|
||||
typedef intrusive::list<
|
||||
context,
|
||||
intrusive::member_hook<
|
||||
context, detail::ready_hook, & context::ready_hook_ >,
|
||||
intrusive::constant_time_size< false > > ready_queue_t;
|
||||
typedef intrusive::set<
|
||||
context,
|
||||
intrusive::member_hook<
|
||||
context, detail::sleep_hook, & context::sleep_hook_ >,
|
||||
intrusive::constant_time_size< false >,
|
||||
intrusive::compare< timepoint_less > > sleep_queue_t;
|
||||
typedef intrusive::list<
|
||||
context,
|
||||
intrusive::member_hook<
|
||||
context, detail::terminated_hook, & context::terminated_hook_ >,
|
||||
context,
|
||||
detail::terminated_hook,
|
||||
& context::terminated_hook_ >,
|
||||
intrusive::constant_time_size< false > > terminated_queue_t;
|
||||
|
||||
context * main_ctx_;
|
||||
intrusive_ptr< context > dispatcher_ctx_;
|
||||
ready_queue_t ready_queue_;
|
||||
sleep_queue_t sleep_queue_;
|
||||
terminated_queue_t terminated_queue_;
|
||||
bool shutdown_;
|
||||
detail::autoreset_event ready_queue_ev_;
|
||||
@@ -47,6 +65,8 @@ private:
|
||||
|
||||
void release_terminated_();
|
||||
|
||||
void woken_up_() noexcept;
|
||||
|
||||
public:
|
||||
scheduler() noexcept;
|
||||
|
||||
@@ -67,6 +87,8 @@ public:
|
||||
|
||||
void yield( context *) noexcept;
|
||||
|
||||
bool wait_until( context *, std::chrono::steady_clock::time_point const&);
|
||||
|
||||
void re_schedule( context *) noexcept;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user