| @@ -9,3 +9,6 @@ Option ( ASYNCPP_INSTALL_PACKAGE | |||
| Option ( ASYNCPP_USE_GIT_VERSION | |||
| "Read the git tags to get the version of asyncpp" | |||
| ON ) | |||
| Option ( ASYNCPP_FEATURE_TIMING_ENABLED | |||
| "Enable the timing features of asyncpp" | |||
| ON ) | |||
| @@ -0,0 +1,3 @@ | |||
| #pragma once | |||
| #cmakedefine ASYNCPP_FEATURE_TIMING_ENABLED | |||
| @@ -1,3 +1,9 @@ | |||
| #pragma once | |||
| #include <asyncpp/config.h> | |||
| #include <asyncpp/core.h> | |||
| #ifdef ASYNCPP_FEATURE_TIMING_ENABLED | |||
| #include <asyncpp/timing.h> | |||
| #endif | |||
| @@ -6,6 +6,6 @@ | |||
| #include "future/lazy.inl" | |||
| #include "future/and_then.inl" | |||
| #ifdef asyncpp_timing | |||
| #ifdef ASYNCPP_FEATURE_TIMING_ENABLED | |||
| #include "future/timeout.inl" | |||
| #endif | |||
| @@ -57,7 +57,7 @@ namespace asyncpp | |||
| typename X_lambda> | |||
| inline auto and_then(X_lambda&& p_lambda) &&; | |||
| #ifdef asyncpp_timing | |||
| #ifdef ASYNCPP_FEATURE_TIMING_ENABLED | |||
| public: | |||
| /** | |||
| * @brief Throw an execption if the timeout has passed. | |||
| @@ -1,5 +1,7 @@ | |||
| #pragma once | |||
| #include <asyncpp/timing/timeout/timeout_future.h> | |||
| #include "future.h" | |||
| namespace asyncpp { | |||
| @@ -22,11 +24,11 @@ namespace __future { | |||
| derived_type const &, | |||
| derived_type &>; | |||
| using derived_forward_type = forward_type_t<X_mode, derived_ref_type>; | |||
| using timeout_type = asyncpp::timing::timeout<derived_storage_type>; | |||
| using timeout_future_type = asyncpp::timing::timeout_future<derived_storage_type>; | |||
| auto& self = static_cast<derived_ref_type>(p_self); | |||
| return timeout_type( | |||
| return timeout_future_type( | |||
| std::forward<derived_forward_type>(self), | |||
| p_timeout); | |||
| } | |||
| @@ -6,6 +6,6 @@ | |||
| #include "stream/flatten.inl" | |||
| #include "stream/for_each.inl" | |||
| #ifdef asyncpp_timing | |||
| #ifdef ASYNCPP_FEATURE_TIMING_ENABLED | |||
| #include "stream/timeout.inl" | |||
| #endif | |||
| @@ -75,7 +75,7 @@ namespace asyncpp | |||
| chaining_mode X_mode = move> | |||
| inline auto flatten() &&; | |||
| #ifdef asyncpp_timing | |||
| #ifdef ASYNCPP_FEATURE_TIMING_ENABLED | |||
| public: | |||
| /** | |||
| * @brief Throw an execption if the timeout has passed. | |||
| @@ -1,5 +1,7 @@ | |||
| #pragma once | |||
| #include <asyncpp/timing/timeout/timeout_stream.h> | |||
| #include "stream.h" | |||
| namespace asyncpp { | |||
| @@ -22,11 +24,11 @@ namespace __stream { | |||
| derived_type const &, | |||
| derived_type &>; | |||
| using derived_forward_type = forward_type_t<X_mode, derived_ref_type>; | |||
| using timeout_type = timing::timeout<derived_storage_type>; | |||
| using timeout_stream_type = timing::timeout_stream<derived_storage_type>; | |||
| auto& self = static_cast<derived_ref_type>(p_self); | |||
| return timeout_type( | |||
| return timeout_stream_type( | |||
| std::forward<derived_forward_type>(self), | |||
| p_timeout); | |||
| } | |||
| @@ -59,6 +59,9 @@ namespace asyncpp | |||
| */ | |||
| inline lock(task::handle_ptr_s p_handle); | |||
| inline lock(lock &&) = delete; | |||
| inline lock(lock const &) = delete; | |||
| /** | |||
| * @brief Destructor. | |||
| */ | |||
| @@ -1,5 +1,7 @@ | |||
| #pragma once | |||
| #include <cppcore/misc/exception.h> | |||
| #include "task.h" | |||
| namespace asyncpp | |||
| @@ -8,7 +10,12 @@ namespace asyncpp | |||
| /* task::lock */ | |||
| task::lock::lock(task::handle_ptr_s p_handle) | |||
| { local_storage().current = p_handle; } | |||
| { | |||
| auto& current = local_storage().current; | |||
| if (!current.expired()) | |||
| throw cppcore::invalid_operation_exception("Current task is already assigned!"); | |||
| current = p_handle; | |||
| } | |||
| task::lock::~lock() | |||
| { local_storage().current.reset(); } | |||
| @@ -1,5 +1,7 @@ | |||
| #pragma once | |||
| #include <cppcore/misc/exception.h> | |||
| #include "executor.h" | |||
| #include "task_handle.inl" | |||
| @@ -33,7 +35,12 @@ namespace executor { | |||
| /* lock */ | |||
| executor::lock::lock(executor& p_current) | |||
| { executor::local_storage().current = &p_current; } | |||
| { | |||
| auto& current = executor::local_storage().current; | |||
| if (current) | |||
| throw cppcore::invalid_operation_exception("Current executor is already assigned!"); | |||
| current = &p_current; | |||
| } | |||
| executor::lock::~lock() | |||
| { executor::local_storage().current = nullptr; } | |||
| @@ -1,13 +1,8 @@ | |||
| #pragma once | |||
| #define asyncpp_timing | |||
| #define ASYNCPP_FEATURE_TIMING_ENABLED | |||
| #include "timing/delay.h" | |||
| #include "timing/interval.h" | |||
| #include "timing/timeout.h" | |||
| #include "timing/timer.h" | |||
| #include "timing/delay.inl" | |||
| #include "timing/interval.inl" | |||
| #include "timing/timeout.inl" | |||
| #include "timing/timer.inl" | |||
| @@ -1,64 +1,5 @@ | |||
| #pragma once | |||
| #include <asyncpp/core/misc.h> | |||
| #include <asyncpp/core/future/future.h> | |||
| #include "delay/delay.h" | |||
| #include "timer.h" | |||
| #include "delay.pre.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| struct delay final | |||
| : public base_future<void, delay> | |||
| { | |||
| public: | |||
| using value_type = void; | |||
| using base_future_type = base_future<void, delay>; | |||
| using result_type = typename base_future_type::result_type; | |||
| private: | |||
| time_point _deadline; | |||
| __impl::registration_ptr_w _registration; | |||
| public: | |||
| /** | |||
| * @brief Constructor. Create a delay at the given deadline. | |||
| */ | |||
| inline delay(const time_point& p_deadline); | |||
| /** | |||
| * @brief Constructor. Create a delay with the given duration. | |||
| */ | |||
| template<typename T_base, typename T_ratio> | |||
| inline delay(const duration<T_base, T_ratio>& p_duration); | |||
| /** | |||
| * @brief Destructor. | |||
| */ | |||
| inline ~delay(); | |||
| /** | |||
| * @brief Get the current deadline of the delay. | |||
| */ | |||
| inline time_point deadline() const; | |||
| /** | |||
| * @brief Reset the delay to a new time point. | |||
| */ | |||
| inline void reset(const time_point& p_deadline); | |||
| /** | |||
| * @brief Reset the delay to the given duration. | |||
| */ | |||
| template<typename T_base, typename T_ratio> | |||
| inline void reset(const duration<T_base, T_ratio>& p_duration); | |||
| public: /* future */ | |||
| /** | |||
| * @brief Poll the result from the future. | |||
| */ | |||
| inline result_type poll(); | |||
| }; | |||
| } } | |||
| #include "delay/delay.inl" | |||
| @@ -0,0 +1,65 @@ | |||
| #pragma once | |||
| #include <asyncpp/core/misc.h> | |||
| #include <asyncpp/core/future/future.h> | |||
| #include "delay.pre.h" | |||
| #include "../timer/timer.h" | |||
| #include "../timer/resource.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| struct delay final | |||
| : public base_future<void, delay> | |||
| { | |||
| public: | |||
| using value_type = void; | |||
| using base_future_type = base_future<void, delay>; | |||
| using result_type = typename base_future_type::result_type; | |||
| private: | |||
| time_point _deadline; | |||
| __impl::resource_ptr_w _resource; | |||
| public: | |||
| /** | |||
| * @brief Constructor. Create a delay at the given deadline. | |||
| */ | |||
| inline delay(const time_point& p_deadline); | |||
| /** | |||
| * @brief Constructor. Create a delay with the given duration. | |||
| */ | |||
| template<typename T_base, typename T_ratio> | |||
| inline delay(const duration<T_base, T_ratio>& p_duration); | |||
| /** | |||
| * @brief Destructor. | |||
| */ | |||
| inline ~delay(); | |||
| /** | |||
| * @brief Get the current deadline of the delay. | |||
| */ | |||
| inline time_point deadline() const; | |||
| /** | |||
| * @brief Reset the delay to a new time point. | |||
| */ | |||
| inline void reset(const time_point& p_deadline); | |||
| /** | |||
| * @brief Reset the delay to the given duration. | |||
| */ | |||
| template<typename T_base, typename T_ratio> | |||
| inline void reset(const duration<T_base, T_ratio>& p_duration); | |||
| public: /* future */ | |||
| /** | |||
| * @brief Poll the result from the future. | |||
| */ | |||
| inline result_type poll(); | |||
| }; | |||
| } } | |||
| @@ -5,7 +5,7 @@ | |||
| #include "delay.h" | |||
| #include "timer.inl" | |||
| #include "../timer/timer_base.inl" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| @@ -13,32 +13,32 @@ namespace timing { | |||
| /* delay */ | |||
| delay::delay(const time_point& p_deadline) | |||
| : _deadline (p_deadline) | |||
| , _registration () | |||
| : _deadline (p_deadline) | |||
| , _resource () | |||
| { } | |||
| template<typename T_base, typename T_ratio> | |||
| delay::delay(const duration<T_base, T_ratio>& p_duration) | |||
| : _deadline (asyncpp::now() + p_duration) | |||
| , _registration () | |||
| : _deadline (asyncpp::now() + p_duration) | |||
| , _resource () | |||
| { } | |||
| inline delay::~delay() | |||
| { __impl::timer_base::unregister_resource(_registration); } | |||
| { __impl::timer_base::unregister_resource(_resource); } | |||
| time_point delay::deadline() const | |||
| { return _deadline; } | |||
| void delay::reset(const time_point& p_deadline) | |||
| { | |||
| __impl::timer_base::unregister_resource(_registration); | |||
| __impl::timer_base::unregister_resource(_resource); | |||
| _deadline = p_deadline; | |||
| } | |||
| template<typename T_base, typename T_ratio> | |||
| void delay::reset(const duration<T_base, T_ratio>& p_duration) | |||
| { | |||
| __impl::timer_base::unregister_resource(_registration); | |||
| __impl::timer_base::unregister_resource(_resource); | |||
| _deadline = asyncpp::now() + p_duration; | |||
| } | |||
| @@ -51,8 +51,8 @@ namespace timing { | |||
| if (_deadline <= now) | |||
| return result_type::ready(); | |||
| if (_registration.expired()) | |||
| _registration = timing::__impl::timer_base::register_resource(_deadline); | |||
| if (_resource.expired()) | |||
| _resource = timing::__impl::timer_base::register_resource(_deadline); | |||
| return result_type::not_ready(); | |||
| } | |||
| @@ -1,88 +0,0 @@ | |||
| #pragma once | |||
| #include <set> | |||
| #include <memory> | |||
| #include <cppcore/synchronization/locked.h> | |||
| #include <asyncpp/core/misc.h> | |||
| #include "timer_base.pre.h" | |||
| #include "registration.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl { | |||
| struct timer_base | |||
| { | |||
| private: | |||
| struct registration_less_compare | |||
| { | |||
| constexpr bool operator()( | |||
| const registration_ptr_s& lhs, | |||
| const registration_ptr_s& rhs) const; | |||
| }; | |||
| using registration_set = std::set<registration_ptr_s, registration_less_compare>; | |||
| protected: | |||
| cppcore::locked<registration_set> _registrations; | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| inline ~timer_base(); | |||
| public: | |||
| /** | |||
| * @brief Get the number of resources assigned to this timer_base. | |||
| */ | |||
| inline size_t resource_count() const; | |||
| /** | |||
| * @brief Set the thread local current timer_base. | |||
| */ | |||
| inline void make_current(); | |||
| /** | |||
| * @brief Set the thread local current timer_base. | |||
| */ | |||
| inline void clear_current(); | |||
| public: | |||
| /** | |||
| * @brief Get the thread local timer_base instance. | |||
| */ | |||
| static inline timer_base* current(); | |||
| /** | |||
| * @brief Register a new resource within this timer_base. | |||
| */ | |||
| static inline registration_ptr_w register_resource(const time_point& p_deadline); | |||
| /** | |||
| * @brief Register a new resource within this timer_base. | |||
| */ | |||
| static inline void unregister_resource(registration_ptr_w& p_value); | |||
| private: | |||
| /** | |||
| * @brief Create registration for a new resource. | |||
| */ | |||
| registration_ptr_w create_registration(const time_point& p_deadline); | |||
| protected: | |||
| struct storage | |||
| { | |||
| timer_base* current { nullptr }; | |||
| }; | |||
| /** | |||
| * @brief Get the thread local storage. | |||
| */ | |||
| static inline storage& local_storage(); | |||
| }; | |||
| } } } | |||
| @@ -1,91 +0,0 @@ | |||
| #pragma once | |||
| #include "timer_base.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl { | |||
| /* timer_base::inner_less_compare */ | |||
| constexpr bool timer_base::registration_less_compare::operator()( | |||
| const registration_ptr_s& lhs, | |||
| const registration_ptr_s& rhs) const | |||
| { | |||
| return (lhs->deadline < rhs->deadline) | |||
| ? true | |||
| : | |||
| (lhs->deadline == rhs->deadline) | |||
| && (lhs.get() < rhs.get()) | |||
| ? true | |||
| : false; | |||
| } | |||
| /* timer_base */ | |||
| timer_base::~timer_base() | |||
| { | |||
| auto& s = local_storage(); | |||
| if (s.current == this) | |||
| s.current = nullptr; | |||
| } | |||
| size_t timer_base::resource_count() const | |||
| { return _registrations.lock()->size(); } | |||
| void timer_base::make_current() | |||
| { | |||
| auto& s = local_storage(); | |||
| if (s.current) | |||
| throw std::runtime_error("Thread local timer_base instance is already assigned!"); | |||
| s.current = this; | |||
| } | |||
| void timer_base::clear_current() | |||
| { | |||
| auto& s = local_storage(); | |||
| if (s.current && s.current != this) | |||
| throw std::runtime_error("Thread local timer_base instance is not assigned to this instance!"); | |||
| s.current = nullptr; | |||
| } | |||
| timer_base* timer_base::current() | |||
| { return local_storage().current; } | |||
| registration_ptr_w timer_base::register_resource(const time_point& p_deadline) | |||
| { | |||
| auto t = current(); | |||
| if (!t) | |||
| throw std::runtime_error("Thread local timer_base instance is not assigned!"); | |||
| return t->create_registration(p_deadline); | |||
| } | |||
| registration_ptr_w timer_base::create_registration(const time_point& p_deadline) | |||
| { | |||
| auto r = std::make_shared<registration>( | |||
| *this, | |||
| p_deadline, | |||
| task::current()); | |||
| _registrations.lock()->insert(r); | |||
| return r; | |||
| } | |||
| void timer_base::unregister_resource(registration_ptr_w& p_value) | |||
| { | |||
| auto s = p_value.lock(); | |||
| p_value.reset(); | |||
| if (s) | |||
| s->owner._registrations.lock()->erase(s); | |||
| } | |||
| timer_base::storage& timer_base::local_storage() | |||
| { | |||
| thread_local storage value; | |||
| return value; | |||
| } | |||
| } } } | |||
| @@ -1,80 +0,0 @@ | |||
| #pragma once | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| template<typename T_inner = void> | |||
| struct timer; | |||
| namespace __impl | |||
| { | |||
| /* timer_impl - default */ | |||
| template<typename T_inner> | |||
| struct timer_impl | |||
| { | |||
| public: | |||
| using inner_type = T_inner; | |||
| using owner_type = timer<inner_type>; | |||
| using inner_thread_lock_type = decltype(std::declval<inner_type>().init_thread()); | |||
| struct thread_lock | |||
| { | |||
| inner_thread_lock_type inner_lock; | |||
| template<typename... X_args> | |||
| inline thread_lock(X_args&&... p_args); | |||
| inline ~thread_lock(); | |||
| }; | |||
| using thread_lock_ptr_u = std::unique_ptr<thread_lock>; | |||
| public: | |||
| owner_type& owner; | |||
| inner_type inner; | |||
| public: | |||
| template<typename... X_args> | |||
| inline timer_impl( | |||
| owner_type& p_owner, | |||
| X_args&&... p_args); | |||
| inline void idle( | |||
| const time_point * p_deadline); | |||
| inline thread_lock_ptr_u init_thread(); | |||
| }; | |||
| /* timer_impl<void> */ | |||
| template<> | |||
| struct timer_impl<void> | |||
| { | |||
| public: | |||
| using owner_type = timer<void>; | |||
| struct thread_lock | |||
| { | |||
| inline ~thread_lock(); | |||
| }; | |||
| using thread_lock_ptr_u = std::unique_ptr<thread_lock>; | |||
| public: | |||
| owner_type& owner; | |||
| public: | |||
| inline timer_impl( | |||
| owner_type& p_owner); | |||
| inline void idle( | |||
| const time_point * p_deadline); | |||
| inline thread_lock_ptr_u init_thread(); | |||
| }; | |||
| } | |||
| } } | |||
| @@ -1,73 +0,0 @@ | |||
| #pragma once | |||
| #include "timer_impl.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl { | |||
| /* timer_impl::thread_lock - default */ | |||
| template<typename T_inner> | |||
| template<typename... X_args> | |||
| timer_impl<T_inner>::thread_lock::thread_lock(X_args&&... p_args) | |||
| : inner_lock(std::forward<X_args>(p_args)...) | |||
| { } | |||
| template<typename T_inner> | |||
| timer_impl<T_inner>::thread_lock::~thread_lock() | |||
| { owner_type::local_storage().current = nullptr; } | |||
| /* timer_impl - default */ | |||
| template<typename T_inner> | |||
| template<typename... X_args> | |||
| timer_impl<T_inner>::timer_impl( | |||
| owner_type& p_owner, | |||
| X_args&&... p_args) | |||
| : owner(p_owner) | |||
| , inner(std::forward<X_args>(p_args)...) | |||
| { } | |||
| template<typename T_inner> | |||
| void timer_impl<T_inner>::idle(const time_point * p_deadline) | |||
| { | |||
| { | |||
| auto r = owner._registrations.lock(); | |||
| if (!r->empty()) | |||
| { | |||
| p_deadline = merge_deadlines(p_deadline, &(*r->begin())->deadline); | |||
| } | |||
| } | |||
| inner.idle(p_deadline); | |||
| } | |||
| template<typename T_inner> | |||
| typename timer_impl<T_inner>::thread_lock_ptr_u | |||
| timer_impl<T_inner>::init_thread() | |||
| { return std::make_unique<thread_lock>(inner.init_thread()); } | |||
| /* timer_impl<void>::thread_lock - default */ | |||
| timer_impl<void>::thread_lock::~thread_lock() | |||
| { owner_type::local_storage().current = nullptr; } | |||
| /* timer_impl<void> */ | |||
| timer_impl<void>::timer_impl( | |||
| owner_type& p_owner) | |||
| : owner(p_owner) | |||
| { } | |||
| void timer_impl<void>::idle( | |||
| const time_point * p_deadline) | |||
| { } | |||
| timer_impl<void>::thread_lock_ptr_u | |||
| timer_impl<void>::init_thread() | |||
| { return std::unique_ptr<thread_lock>(); } | |||
| } } } | |||
| @@ -1,55 +1,5 @@ | |||
| #pragma once | |||
| #include <asyncpp/core/misc.h> | |||
| #include <asyncpp/core/future/future.h> | |||
| #include <asyncpp/core/stream/stream.h> | |||
| #include "interval/interval.h" | |||
| #include "delay.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| struct interval final | |||
| : public base_stream<void, interval> | |||
| { | |||
| public: | |||
| using value_type = void; | |||
| using base_stream_type = base_stream<void, delay>; | |||
| using result_type = typename base_stream_type::result_type; | |||
| private: | |||
| delay _delay; //!< Delay future | |||
| clock::duration _duration; //!< Interval duration. | |||
| time_point _deadline; //!< Deadline after the interval should end. | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| template<typename T_base, typename T_ratio> | |||
| inline interval( | |||
| const duration<T_base, T_ratio>& p_duration, | |||
| time_point p_deadline = time_point()); | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| template<typename T_base, typename T_ratio> | |||
| inline interval( | |||
| const time_point& p_at, | |||
| const duration<T_base, T_ratio>& p_duration, | |||
| time_point p_deadline = time_point()); | |||
| /** | |||
| * @brief Get the duration of the interval. | |||
| */ | |||
| inline const clock::duration& duration() const; | |||
| public: /* stream */ | |||
| /** | |||
| * @brief Poll the result from the stream. | |||
| */ | |||
| inline result_type poll(); | |||
| }; | |||
| } } | |||
| #include "interval/interval.inl" | |||
| @@ -0,0 +1,55 @@ | |||
| #pragma once | |||
| #include <asyncpp/core/misc.h> | |||
| #include <asyncpp/core/future/future.h> | |||
| #include <asyncpp/core/stream/stream.h> | |||
| #include "../delay/delay.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| struct interval final | |||
| : public base_stream<void, interval> | |||
| { | |||
| public: | |||
| using value_type = void; | |||
| using base_stream_type = base_stream<void, delay>; | |||
| using result_type = typename base_stream_type::result_type; | |||
| private: | |||
| delay _delay; //!< Delay future | |||
| clock::duration _duration; //!< Interval duration. | |||
| time_point _deadline; //!< Deadline after the interval should end. | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| template<typename T_base, typename T_ratio> | |||
| inline interval( | |||
| const duration<T_base, T_ratio>& p_duration, | |||
| time_point p_deadline = time_point()); | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| template<typename T_base, typename T_ratio> | |||
| inline interval( | |||
| const time_point& p_at, | |||
| const duration<T_base, T_ratio>& p_duration, | |||
| time_point p_deadline = time_point()); | |||
| /** | |||
| * @brief Get the duration of the interval. | |||
| */ | |||
| inline const clock::duration& duration() const; | |||
| public: /* stream */ | |||
| /** | |||
| * @brief Poll the result from the stream. | |||
| */ | |||
| inline result_type poll(); | |||
| }; | |||
| } } | |||
| @@ -2,7 +2,7 @@ | |||
| #include "interval.h" | |||
| #include "delay.inl" | |||
| #include "../delay/delay.inl" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| @@ -1,103 +1,9 @@ | |||
| #pragma once | |||
| #include <cppcore/misc/exception.h> | |||
| #include "timeout/misc.h" | |||
| #include "timeout/timeout_future.h" | |||
| #include "timeout/timeout_stream.h" | |||
| #include <asyncpp/core/misc.h> | |||
| #include <asyncpp/core/future/future.h> | |||
| #include <asyncpp/core/stream/stream.h> | |||
| #include "delay.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| struct timeout_exception | |||
| : public cppcore::exception | |||
| { | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| inline timeout_exception(); | |||
| }; | |||
| template<typename T_inner> | |||
| struct timeout; | |||
| namespace __impl | |||
| { | |||
| template< | |||
| typename T_derived, | |||
| typename = void> | |||
| struct timeout_impl; | |||
| template< | |||
| typename T_inner> | |||
| struct timeout_impl< | |||
| timeout<T_inner>, | |||
| std::enable_if_t<is_future_v<std::decay_t<T_inner>>>> | |||
| : public base_future< | |||
| typename std::decay_t<T_inner>::value_type, | |||
| timeout<T_inner>> | |||
| { | |||
| private: | |||
| using derived_type = timeout<T_inner>; | |||
| public: | |||
| auto poll(); | |||
| }; | |||
| template< | |||
| typename T_inner> | |||
| struct timeout_impl< | |||
| timeout<T_inner>, | |||
| std::enable_if_t<is_stream_v<std::decay_t<T_inner>>>> | |||
| : public base_stream< | |||
| typename std::decay_t<T_inner>::value_type, | |||
| timeout<T_inner>> | |||
| { | |||
| private: | |||
| using derived_type = timeout<T_inner>; | |||
| public: | |||
| auto poll(); | |||
| }; | |||
| } | |||
| template<typename T_inner> | |||
| struct timeout final | |||
| : public __impl::timeout_impl<timeout<T_inner>> | |||
| { | |||
| public: | |||
| using inner_type = T_inner; | |||
| using value_type = typename std::decay_t<inner_type>::value_type; | |||
| using this_type = timeout<inner_type>; | |||
| using impl_type = __impl::timeout_impl<this_type>; | |||
| friend impl_type; | |||
| private: | |||
| inner_type _inner; //!< Inner future / stream. | |||
| clock::duration _timeout; //!< Timeout. | |||
| delay _delay; //!< Delay future. | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| template<typename X_inner, typename X_base, typename X_ratio> | |||
| inline timeout( | |||
| X_inner&& p_inner, | |||
| const duration<X_base, X_ratio>& p_timeout); | |||
| /** | |||
| * @brief Reset the deadline. | |||
| */ | |||
| template<typename X_base, typename X_ratio> | |||
| inline void reset( | |||
| const duration<X_base, X_ratio>& p_timeout); | |||
| }; | |||
| } } | |||
| #include "timeout/misc.inl" | |||
| #include "timeout/timeout_future.inl" | |||
| #include "timeout/timeout_stream.inl" | |||
| @@ -1,96 +0,0 @@ | |||
| #pragma once | |||
| #include "timeout.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl | |||
| { | |||
| template< | |||
| typename T_inner> | |||
| auto timeout_impl< | |||
| timeout<T_inner>, | |||
| std::enable_if_t<is_future_v<std::decay_t<T_inner>>>> | |||
| ::poll() | |||
| { | |||
| auto& self = static_cast<derived_type&>(*this); | |||
| auto r = self._inner.poll(); | |||
| if ( r.is_not_ready() | |||
| && self._delay.poll()) | |||
| { | |||
| auto new_deadline = self._delay.deadline() + self._timeout; | |||
| self._delay.reset(new_deadline); | |||
| throw timing::timeout_exception(); | |||
| } | |||
| return r; | |||
| } | |||
| template< | |||
| typename T_inner> | |||
| auto timeout_impl< | |||
| timeout<T_inner>, | |||
| std::enable_if_t<is_stream_v<std::decay_t<T_inner>>>> | |||
| ::poll() | |||
| { | |||
| auto& self = static_cast<derived_type&>(*this); | |||
| auto r = self._inner.poll(); | |||
| if (r.is_not_ready()) | |||
| { | |||
| if (self._delay.poll()) | |||
| { | |||
| self._delay.reset(self._timeout); | |||
| throw timing::timeout_exception(); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| self._delay.reset(self._timeout); | |||
| } | |||
| return r; | |||
| } | |||
| } | |||
| /* timeout_exception */ | |||
| timeout_exception::timeout_exception() | |||
| : cppcore::exception::exception("timeout") | |||
| { } | |||
| /* timer */ | |||
| template< | |||
| typename T_inner> | |||
| template< | |||
| typename X_inner, | |||
| typename X_base, | |||
| typename X_ratio> | |||
| timeout<T_inner> | |||
| ::timeout( | |||
| X_inner&& p_inner, | |||
| const duration<X_base, X_ratio>& p_duration) | |||
| : _inner (std::forward<X_inner>(p_inner)) | |||
| , _timeout (p_duration) | |||
| , _delay (asyncpp::now() + p_duration) | |||
| { } | |||
| template< | |||
| typename T_inner> | |||
| template< | |||
| typename X_base, | |||
| typename X_ratio> | |||
| void timeout<T_inner> | |||
| ::reset(const duration<X_base, X_ratio>& p_duration) | |||
| { | |||
| _timeout = p_duration; | |||
| _delay.reset(asyncpp::now() + p_duration); | |||
| } | |||
| } } | |||
| @@ -0,0 +1,18 @@ | |||
| #pragma once | |||
| #include <cppcore/misc/exception.h> | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| struct timeout_exception | |||
| : public cppcore::exception | |||
| { | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| inline timeout_exception(); | |||
| }; | |||
| } } | |||
| @@ -0,0 +1,14 @@ | |||
| #pragma once | |||
| #include "misc.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| /* timeout_exception */ | |||
| timeout_exception::timeout_exception() | |||
| : cppcore::exception::exception("timeout") | |||
| { } | |||
| } } | |||
| @@ -0,0 +1,50 @@ | |||
| #pragma once | |||
| #include <asyncpp/core/future/future.h> | |||
| #include "../delay/delay.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| template<typename T_inner> | |||
| struct timeout_future final | |||
| : public base_future< | |||
| typename std::decay_t<T_inner>::value_type, | |||
| timeout_future<T_inner>> | |||
| { | |||
| public: | |||
| using inner_type = T_inner; | |||
| using value_type = typename std::decay_t<inner_type>::value_type; | |||
| using this_type = timeout_future<inner_type>; | |||
| using base_future_type = base_future<value_type, this_type>; | |||
| using result_type = typename base_future_type::result_type; | |||
| private: | |||
| inner_type _inner; //!< Inner future. | |||
| clock::duration _timeout; //!< Timeout. | |||
| delay _delay; //!< Delay future. | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| template<typename X_inner, typename X_base, typename X_ratio> | |||
| inline timeout_future( | |||
| X_inner&& p_inner, | |||
| const duration<X_base, X_ratio>& p_timeout); | |||
| /** | |||
| * @brief Reset the deadline. | |||
| */ | |||
| template<typename X_base, typename X_ratio> | |||
| inline void reset( | |||
| const duration<X_base, X_ratio>& p_timeout); | |||
| /** | |||
| * @brief Poll the result from the future. | |||
| */ | |||
| inline result_type poll(); | |||
| }; | |||
| } } | |||
| @@ -0,0 +1,55 @@ | |||
| #pragma once | |||
| #include "timeout_future.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| /* timeout_future */ | |||
| template< | |||
| typename T_inner> | |||
| template< | |||
| typename X_inner, | |||
| typename X_base, | |||
| typename X_ratio> | |||
| timeout_future<T_inner>::timeout_future( | |||
| X_inner&& p_inner, | |||
| const duration<X_base, X_ratio>& p_timeout) | |||
| : _inner (std::forward<X_inner>(p_inner)) | |||
| , _timeout (p_timeout) | |||
| , _delay (asyncpp::now() + p_timeout) | |||
| { } | |||
| template< | |||
| typename T_inner> | |||
| template< | |||
| typename X_base, | |||
| typename X_ratio> | |||
| void timeout_future<T_inner> | |||
| ::reset(const duration<X_base, X_ratio>& p_timeout) | |||
| { | |||
| _timeout = p_timeout; | |||
| _delay.reset(_timeout); | |||
| } | |||
| template< | |||
| typename T_inner> | |||
| typename timeout_future<T_inner>::result_type | |||
| timeout_future<T_inner> | |||
| ::poll() | |||
| { | |||
| auto r = _inner.poll(); | |||
| if ( r.is_not_ready() | |||
| && _delay.poll()) | |||
| { | |||
| auto new_deadline = _delay.deadline() + _timeout; | |||
| _delay.reset(new_deadline); | |||
| throw timing::timeout_exception(); | |||
| } | |||
| return r; | |||
| } | |||
| } } | |||
| @@ -0,0 +1,50 @@ | |||
| #pragma once | |||
| #include <asyncpp/core/stream/stream.h> | |||
| #include "../delay/delay.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| template<typename T_inner> | |||
| struct timeout_stream final | |||
| : public base_stream< | |||
| typename std::decay_t<T_inner>::value_type, | |||
| timeout_stream<T_inner>> | |||
| { | |||
| public: | |||
| using inner_type = T_inner; | |||
| using value_type = typename std::decay_t<inner_type>::value_type; | |||
| using this_type = timeout_stream<inner_type>; | |||
| using base_stream_type = base_stream<value_type, this_type>; | |||
| using result_type = typename base_stream_type::result_type; | |||
| private: | |||
| inner_type _inner; //!< Inner stream. | |||
| clock::duration _timeout; //!< Timeout. | |||
| delay _delay; //!< Delay stream. | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| template<typename X_inner, typename X_base, typename X_ratio> | |||
| inline timeout_stream( | |||
| X_inner&& p_inner, | |||
| const duration<X_base, X_ratio>& p_timeout); | |||
| /** | |||
| * @brief Reset the deadline. | |||
| */ | |||
| template<typename X_base, typename X_ratio> | |||
| inline void reset( | |||
| const duration<X_base, X_ratio>& p_timeout); | |||
| /** | |||
| * @brief Poll the result from the future. | |||
| */ | |||
| inline result_type poll(); | |||
| }; | |||
| } } | |||
| @@ -0,0 +1,60 @@ | |||
| #pragma once | |||
| #include "timeout_stream.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| /* timeout_stream */ | |||
| template< | |||
| typename T_inner> | |||
| template< | |||
| typename X_inner, | |||
| typename X_base, | |||
| typename X_ratio> | |||
| timeout_stream<T_inner>::timeout_stream( | |||
| X_inner&& p_inner, | |||
| const duration<X_base, X_ratio>& p_timeout) | |||
| : _inner (std::forward<X_inner>(p_inner)) | |||
| , _timeout (p_timeout) | |||
| , _delay (asyncpp::now() + p_timeout) | |||
| { } | |||
| template< | |||
| typename T_inner> | |||
| template< | |||
| typename X_base, | |||
| typename X_ratio> | |||
| void timeout_stream<T_inner> | |||
| ::reset(const duration<X_base, X_ratio>& p_timeout) | |||
| { | |||
| _timeout = p_timeout; | |||
| _delay.reset(_timeout); | |||
| } | |||
| template< | |||
| typename T_inner> | |||
| typename timeout_stream<T_inner>::result_type | |||
| timeout_stream<T_inner> | |||
| ::poll() | |||
| { | |||
| auto r = _inner.poll(); | |||
| if (r.is_not_ready()) | |||
| { | |||
| if (_delay.poll()) | |||
| { | |||
| _delay.reset(_timeout); | |||
| throw timing::timeout_exception(); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| _delay.reset(_timeout); | |||
| } | |||
| return r; | |||
| } | |||
| } } | |||
| @@ -1,50 +1,11 @@ | |||
| #pragma once | |||
| #include <set> | |||
| #include <memory> | |||
| #include <cppcore/synchronization/locked.h> | |||
| #include "impl/timer_base.h" | |||
| #include "impl/timer_impl.h" | |||
| #include "impl/registration.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| template<typename T_inner> | |||
| struct timer | |||
| : public __impl::timer_base | |||
| { | |||
| public: | |||
| template<typename X> | |||
| friend struct __impl::timer_impl; | |||
| using inner_type = T_inner; | |||
| using timer_impl_type = __impl::timer_impl<inner_type>; | |||
| private: | |||
| timer_impl_type _impl; | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| template<typename... X_args> | |||
| inline timer(X_args&&... p_args); | |||
| /** | |||
| * @brief Handle idle of the runtime. | |||
| * | |||
| * This method is called as soon as the runtime has nothing to do. | |||
| * The passed deadline is the timepoint the method should return (or null if not set). | |||
| */ | |||
| inline void idle(const time_point * p_deadline); | |||
| /** | |||
| * @brief This method is calld by the executor when a new thread needs to be initialized. | |||
| */ | |||
| inline decltype(auto) init_thread(); | |||
| }; | |||
| } } | |||
| #include "timer/timer.h" | |||
| #include "timer/timer_base.h" | |||
| #include "timer/timer_impl.h" | |||
| #include "timer/resource.h" | |||
| #include "timer/timer.inl" | |||
| #include "timer/timer_base.inl" | |||
| #include "timer/timer_impl.inl" | |||
| #include "timer/resource.inl" | |||
| @@ -11,7 +11,7 @@ namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl { | |||
| struct registration | |||
| struct resource | |||
| { | |||
| public: | |||
| timer_base& owner; | |||
| @@ -21,13 +21,13 @@ namespace __impl { | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| inline registration( | |||
| inline resource( | |||
| timer_base& p_owner, | |||
| const time_point& p_deadline, | |||
| const asyncpp::task& p_task); | |||
| }; | |||
| using registration_ptr_w = std::weak_ptr<registration>; | |||
| using registration_ptr_s = std::shared_ptr<registration>; | |||
| using resource_ptr_w = std::weak_ptr<resource>; | |||
| using resource_ptr_s = std::shared_ptr<resource>; | |||
| } } } | |||
| @@ -1,14 +1,14 @@ | |||
| #pragma once | |||
| #include "registration.h" | |||
| #include "resource.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl { | |||
| /* registration */ | |||
| /* resource */ | |||
| registration::registration( | |||
| resource::resource( | |||
| timer_base& p_owner, | |||
| const time_point& p_deadline, | |||
| const asyncpp::task& p_task) | |||
| @@ -0,0 +1,44 @@ | |||
| #pragma once | |||
| #include <set> | |||
| #include <memory> | |||
| #include <cppcore/synchronization/locked.h> | |||
| #include "timer_impl.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| template<typename T_inner = void> | |||
| struct timer | |||
| : public __impl::timer_impl<T_inner> | |||
| { | |||
| public: | |||
| using base_type = __impl::timer_impl<T_inner>; | |||
| using inner_type = T_inner; | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| template<typename... X_args> | |||
| inline timer(X_args&&... p_args); | |||
| /** | |||
| * @brief Handle idle of the runtime. | |||
| * | |||
| * This method is called as soon as the runtime has nothing to do. | |||
| * The passed deadline is the timepoint the method should return (or null if not set). | |||
| */ | |||
| inline void idle(const time_point * p_deadline); | |||
| /** | |||
| * @brief This method is calld by the executor when a new thread needs to be initialized. | |||
| * | |||
| * @return Object to hold as long as the thread is active on this timer. | |||
| */ | |||
| inline auto init_thread(); | |||
| }; | |||
| } } | |||
| @@ -1,11 +1,8 @@ | |||
| #pragma once | |||
| #include "timer.h" | |||
| #include "delay.inl" | |||
| #include "impl/timer_base.inl" | |||
| #include "impl/timer_impl.inl" | |||
| #include "impl/registration.inl" | |||
| #include "timer_impl.inl" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| @@ -15,7 +12,7 @@ namespace timing { | |||
| template<typename T_inner> | |||
| template<typename... X_args> | |||
| timer<T_inner>::timer(X_args&&... p_args) | |||
| : _impl(*this, std::forward<X_args>(p_args)...) | |||
| : base_type(std::forward<X_args>(p_args)...) | |||
| { } | |||
| template<typename T_inner> | |||
| @@ -24,7 +21,7 @@ namespace timing { | |||
| auto now = asyncpp::now(); | |||
| { | |||
| auto r = _registrations.lock(); | |||
| auto r = this->_resources.lock(); | |||
| auto it = r->begin(); | |||
| while (it != r->end() && now >= (**it).deadline) | |||
| { | |||
| @@ -33,14 +30,11 @@ namespace timing { | |||
| } | |||
| } | |||
| _impl.idle(p_deadline); | |||
| base_type::idle_impl(p_deadline); | |||
| } | |||
| template<typename T_inner> | |||
| decltype(auto) timer<T_inner>::init_thread() | |||
| { | |||
| local_storage().current = this; | |||
| return _impl.init_thread(); | |||
| } | |||
| auto timer<T_inner>::init_thread() | |||
| { return base_type::init_thread_impl(); } | |||
| } } | |||
| @@ -0,0 +1,87 @@ | |||
| #pragma once | |||
| #include <set> | |||
| #include <memory> | |||
| #include <cppcore/synchronization/locked.h> | |||
| #include <asyncpp/core/misc.h> | |||
| #include "timer_base.pre.h" | |||
| #include "resource.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl { | |||
| struct timer_base | |||
| { | |||
| private: | |||
| struct resource_less_compare | |||
| { | |||
| constexpr bool operator()( | |||
| const resource_ptr_s& lhs, | |||
| const resource_ptr_s& rhs) const; | |||
| }; | |||
| using resource_set = std::set<resource_ptr_s, resource_less_compare>; | |||
| protected: | |||
| cppcore::locked<resource_set> _resources; | |||
| public: | |||
| /** | |||
| * @brief Get the number of registered timing resources. | |||
| */ | |||
| inline size_t resource_count(); | |||
| public: | |||
| /** | |||
| * @brief Get the thread local timer_base instance. | |||
| */ | |||
| static inline timer_base* current(); | |||
| /** | |||
| * @brief Register a new resource within this timer_base. | |||
| */ | |||
| static inline resource_ptr_w register_resource(const time_point& p_deadline); | |||
| /** | |||
| * @brief Register a new resource within this timer_base. | |||
| */ | |||
| static inline void unregister_resource(resource_ptr_w& p_value); | |||
| private: | |||
| /** | |||
| * @brief Create resource for a new resource. | |||
| */ | |||
| resource_ptr_w create_resource(const time_point& p_deadline); | |||
| public: | |||
| struct lock | |||
| { | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| inline lock(timer_base& p_timer); | |||
| /** | |||
| * @brief Destructor. | |||
| */ | |||
| inline ~lock(); | |||
| }; | |||
| private: | |||
| struct storage | |||
| { | |||
| timer_base* current { nullptr }; | |||
| }; | |||
| /** | |||
| * @brief Get the thread local storage. | |||
| */ | |||
| static inline storage& local_storage(); | |||
| }; | |||
| } } } | |||
| @@ -0,0 +1,83 @@ | |||
| #pragma once | |||
| #include <cppcore/misc/exception.h> | |||
| #include "timer_base.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl { | |||
| /* timer_base::inner_less_compare */ | |||
| constexpr bool timer_base::resource_less_compare::operator()( | |||
| const resource_ptr_s& lhs, | |||
| const resource_ptr_s& rhs) const | |||
| { | |||
| return (lhs->deadline < rhs->deadline) | |||
| ? true | |||
| : | |||
| (lhs->deadline == rhs->deadline) | |||
| && (lhs.get() < rhs.get()) | |||
| ? true | |||
| : false; | |||
| } | |||
| /* timer_base::lock */ | |||
| timer_base::lock::lock(timer_base& p_timer) | |||
| { | |||
| auto& current = timer_base::local_storage().current; | |||
| if (current) | |||
| throw cppcore::invalid_operation_exception("Current timer is already assigned!"); | |||
| current = &p_timer; | |||
| } | |||
| timer_base::lock::~lock() | |||
| { timer_base::local_storage().current = nullptr; } | |||
| /* timer_base */ | |||
| size_t timer_base::resource_count() | |||
| { return _resources.lock()->size(); } | |||
| timer_base* timer_base::current() | |||
| { return local_storage().current; } | |||
| resource_ptr_w timer_base::register_resource(const time_point& p_deadline) | |||
| { | |||
| auto t = current(); | |||
| if (!t) | |||
| throw cppcore::invalid_operation_exception("Thread local timer_base instance is not assigned!"); | |||
| return t->create_resource(p_deadline); | |||
| } | |||
| void timer_base::unregister_resource(resource_ptr_w& p_value) | |||
| { | |||
| auto s = p_value.lock(); | |||
| p_value.reset(); | |||
| if (s) | |||
| s->owner._resources.lock()->erase(s); | |||
| } | |||
| resource_ptr_w timer_base::create_resource(const time_point& p_deadline) | |||
| { | |||
| auto r = std::make_shared<resource>( | |||
| *this, | |||
| p_deadline, | |||
| task::current()); | |||
| _resources.lock()->insert(r); | |||
| return r; | |||
| } | |||
| timer_base::storage& timer_base::local_storage() | |||
| { | |||
| thread_local storage value; | |||
| return value; | |||
| } | |||
| } } } | |||
| @@ -0,0 +1,10 @@ | |||
| #pragma once | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl { | |||
| template<typename T_inner> | |||
| struct timer_impl; | |||
| } } } | |||
| @@ -0,0 +1,76 @@ | |||
| #pragma once | |||
| #include "timer_impl.h" | |||
| #include "timer_base.h" | |||
| namespace asyncpp { | |||
| namespace timing { | |||
| namespace __impl { | |||
| /* timer_impl - default */ | |||
| template<typename T_inner> | |||
| struct timer_impl | |||
| : public timer_base | |||
| { | |||
| public: | |||
| using inner_type = T_inner; | |||
| using inner_thread_lock_type = decltype(std::declval<inner_type>().init_thread()); | |||
| struct thread_lock | |||
| { | |||
| timer_base::lock timer_lock; | |||
| inner_thread_lock_type inner_lock; | |||
| template<typename... X_args> | |||
| inline thread_lock(timer_base& p_timer, X_args&&... p_args) | |||
| : timer_lock(p_timer) | |||
| , inner_lock(std::forward<X_args>(p_args)...) | |||
| { } | |||
| inline thread_lock(thread_lock &&) = delete; | |||
| inline thread_lock(thread_lock const &) = delete; | |||
| }; | |||
| private: | |||
| inner_type _inner; | |||
| public: | |||
| template<typename X_inner> | |||
| inline timer_impl(X_inner&& p_inner) | |||
| : _inner(std::forward<X_inner>(p_inner)) | |||
| { } | |||
| protected: | |||
| inline void idle_impl(const time_point * p_deadline) | |||
| { | |||
| { | |||
| auto r = _resources.lock(); | |||
| if (!r->empty()) | |||
| { | |||
| p_deadline = merge_deadlines(p_deadline, &(*r->begin())->deadline); | |||
| } | |||
| } | |||
| _inner.idle(p_deadline); | |||
| } | |||
| inline auto init_thread_impl() | |||
| { return thread_lock(*this, _inner.init_thread()); } | |||
| }; | |||
| /* timer_impl - void */ | |||
| template<> | |||
| struct timer_impl<void> | |||
| : public timer_base | |||
| { | |||
| protected: | |||
| inline void idle_impl(const time_point * p_deadline) | |||
| { } | |||
| inline auto init_thread_impl() | |||
| { return timer_base::lock(*this); } | |||
| }; | |||
| } } } | |||
| @@ -9,11 +9,15 @@ Find_Package ( cppcore REQUIRED ) | |||
| # Interface Library ############################################################################### | |||
| Set ( ASYNCPP_GENERATED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated ) | |||
| Configure_File ( ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/config.h.in | |||
| ${ASYNCPP_GENERATED_INCLUDE_DIR}/asyncpp/config.h ) | |||
| Set ( ASYNCPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include ) | |||
| Add_Library ( asyncpp INTERFACE ) | |||
| Target_Include_Directories ( asyncpp | |||
| INTERFACE | |||
| $<BUILD_INTERFACE:${ASYNCPP_INCLUDE_DIR}> | |||
| $<BUILD_INTERFACE:${ASYNCPP_GENERATED_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${ASYNCPP_INSTALL_DIR_INCLUDE}> ) | |||
| Target_Link_Libraries ( asyncpp | |||
| INTERFACE | |||
| @@ -31,6 +35,8 @@ If ( ASYNCPP_INSTALL_HEADER ) | |||
| DESTINATION ${ASYNCPP_INSTALL_DIR_INCLUDE} ) | |||
| Install ( DIRECTORY ${ASYNCPP_INCLUDE_DIR}/asyncpp | |||
| DESTINATION ${ASYNCPP_INSTALL_DIR_INCLUDE} ) | |||
| Install ( DIRECTORY ${ASYNCPP_GENERATED_INCLUDE_DIR}/cppcore | |||
| DESTINATION ${ASYNCPP_INSTALL_DIR_INCLUDE} ) | |||
| Install ( TARGETS asyncpp | |||
| EXPORT asyncpp | |||
| DESTINATION ${ASYNCPP_INSTALL_DIR_INCLUDE} ) | |||
| @@ -3,9 +3,8 @@ | |||
| #include "../../helper/now_mock.h" | |||
| #include "../../helper/runtime_mock.h" | |||
| #include <asyncpp/timing.h> | |||
| #include <asyncpp/executor/current_thread.h> | |||
| #include <asyncpp.h> | |||
| #include <asyncpp/executor/current_thread.h> | |||
| using namespace ::testing; | |||
| using namespace ::asyncpp; | |||
| @@ -3,7 +3,6 @@ | |||
| #include "../../helper/now_mock.h" | |||
| #include <asyncpp.h> | |||
| #include <asyncpp/timing.h> | |||
| using namespace ::testing; | |||
| using namespace ::asyncpp; | |||
| @@ -19,7 +18,7 @@ TEST(delay_tests, poll) | |||
| .WillOnce(Return(time_point(std::chrono::seconds(1000)))); | |||
| asyncpp::timing::timer t; | |||
| t.make_current(); | |||
| timing::__impl::timer_base::lock l(t); | |||
| { | |||
| delay f(time_point(std::chrono::seconds(1000))); | |||
| @@ -3,7 +3,6 @@ | |||
| #include "../../helper/now_mock.h" | |||
| #include <asyncpp.h> | |||
| #include <asyncpp/timing.h> | |||
| using namespace ::testing; | |||
| using namespace ::asyncpp; | |||
| @@ -23,7 +22,7 @@ TEST(interval_tests, poll) | |||
| // 20 / 5 = 4 | |||
| // 4 x Ready | |||
| t.make_current(); | |||
| timing::__impl::timer_base::lock l(t); | |||
| EXPECT_CALL(m, now) | |||
| .WillOnce(Return(time_point(std::chrono::seconds(0)))); | |||
| @@ -2,7 +2,6 @@ | |||
| #include "../../helper/now_mock.h" | |||
| #include <asyncpp/timing.h> | |||
| #include <asyncpp.h> | |||
| using namespace ::testing; | |||
| @@ -68,8 +67,8 @@ TEST(timeout_tests, poll_future_no_timeout) | |||
| InSequence seq; | |||
| StrictMock<now_mock> m; | |||
| asyncpp::timing::timer tmr; | |||
| tmr.make_current(); | |||
| timing::timer tmr; | |||
| timing::__impl::timer_base::lock l(tmr); | |||
| EXPECT_CALL(m, now()) | |||
| .WillOnce(Return(time_point(std::chrono::seconds(0)))); | |||
| @@ -101,8 +100,8 @@ TEST(timeout_tests, poll_future_timeout) | |||
| InSequence seq; | |||
| StrictMock<now_mock> m; | |||
| asyncpp::timing::timer tmr; | |||
| tmr.make_current(); | |||
| timing::timer tmr; | |||
| timing::__impl::timer_base::lock l(tmr); | |||
| EXPECT_CALL(m, now()) | |||
| .WillOnce(Return(time_point(std::chrono::seconds(0)))); | |||
| @@ -133,8 +132,8 @@ TEST(timeout_tests, poll_stream_no_timeout) | |||
| InSequence seq; | |||
| StrictMock<now_mock> m; | |||
| asyncpp::timing::timer tmr; | |||
| tmr.make_current(); | |||
| timing::timer tmr; | |||
| timing::__impl::timer_base::lock l(tmr); | |||
| EXPECT_CALL(m, now()) | |||
| .WillOnce(Return(time_point(std::chrono::seconds(0)))); | |||
| @@ -183,8 +182,8 @@ TEST(timeout_tests, poll_stream_timeout) | |||
| InSequence seq; | |||
| StrictMock<now_mock> m; | |||
| asyncpp::timing::timer tmr; | |||
| tmr.make_current(); | |||
| timing::timer tmr; | |||
| timing::__impl::timer_base::lock l(tmr); | |||
| EXPECT_CALL(m, now()) | |||
| .WillOnce(Return(time_point(std::chrono::seconds(0)))); | |||
| @@ -4,27 +4,18 @@ | |||
| #include "../../helper/runtime_mock.h" | |||
| #include <asyncpp.h> | |||
| #include <asyncpp/timing.h> | |||
| using namespace ::testing; | |||
| using namespace ::asyncpp; | |||
| TEST(timer_tests, current) | |||
| TEST(timer_tests, lock) | |||
| { | |||
| { | |||
| timing::timer t; | |||
| EXPECT_EQ(nullptr, timing::__impl::timer_base::current()); | |||
| t.make_current(); | |||
| EXPECT_EQ(&t, timing::__impl::timer_base::current()); | |||
| t.clear_current(); | |||
| EXPECT_EQ(nullptr, timing::__impl::timer_base::current()); | |||
| t.make_current(); | |||
| { | |||
| timing::__impl::timer_base::lock l(t); | |||
| EXPECT_EQ(&t, timing::__impl::timer_base::current()); | |||
| } | |||
| @@ -39,7 +30,7 @@ TEST(timer_tests, resource_registration) | |||
| .WillRepeatedly(Return(time_point(std::chrono::seconds(0)))); | |||
| timing::timer t; | |||
| t.make_current(); | |||
| timing::__impl::timer_base::lock l(t); | |||
| auto f1 = std::make_unique<timing::delay>(std::chrono::seconds(10)); | |||
| auto f2 = std::make_unique<timing::delay>(std::chrono::seconds(20)); | |||
| @@ -83,7 +74,7 @@ TEST(timer_tests, idle) | |||
| StrictMock<now_mock> nm; | |||
| StrictMock<runtime_mock> rm; | |||
| timing::timer<StrictMock<runtime_mock>&> t(rm); | |||
| t.make_current(); | |||
| timing::__impl::timer_base::lock l(t); | |||
| EXPECT_CALL(nm, now); | |||
| EXPECT_CALL(rm, idle(nullptr)); | |||