Kaynağa Gözat

* Refactored timing classes

master
bergmann 6 yıl önce
ebeveyn
işleme
e9f6a290cb
48 değiştirilmiş dosya ile 776 ekleme ve 764 silme
  1. +3
    -0
      cmake/asyncpp-options.cmake
  2. +3
    -0
      cmake/config.h.in
  3. +6
    -0
      include/asyncpp.h
  4. +1
    -1
      include/asyncpp/core/future.h
  5. +1
    -1
      include/asyncpp/core/future/future.h
  6. +4
    -2
      include/asyncpp/core/future/timeout.inl
  7. +1
    -1
      include/asyncpp/core/stream.h
  8. +1
    -1
      include/asyncpp/core/stream/stream.h
  9. +4
    -2
      include/asyncpp/core/stream/timeout.inl
  10. +3
    -0
      include/asyncpp/core/task/task.h
  11. +8
    -1
      include/asyncpp/core/task/task.inl
  12. +8
    -1
      include/asyncpp/executor/executor.inl
  13. +1
    -6
      include/asyncpp/timing.h
  14. +2
    -61
      include/asyncpp/timing/delay.h
  15. +65
    -0
      include/asyncpp/timing/delay/delay.h
  16. +10
    -10
      include/asyncpp/timing/delay/delay.inl
  17. +0
    -0
      include/asyncpp/timing/delay/delay.pre.h
  18. +0
    -88
      include/asyncpp/timing/impl/timer_base.h
  19. +0
    -91
      include/asyncpp/timing/impl/timer_base.inl
  20. +0
    -80
      include/asyncpp/timing/impl/timer_impl.h
  21. +0
    -73
      include/asyncpp/timing/impl/timer_impl.inl
  22. +2
    -52
      include/asyncpp/timing/interval.h
  23. +55
    -0
      include/asyncpp/timing/interval/interval.h
  24. +1
    -1
      include/asyncpp/timing/interval/interval.inl
  25. +6
    -100
      include/asyncpp/timing/timeout.h
  26. +0
    -96
      include/asyncpp/timing/timeout.inl
  27. +18
    -0
      include/asyncpp/timing/timeout/misc.h
  28. +14
    -0
      include/asyncpp/timing/timeout/misc.inl
  29. +50
    -0
      include/asyncpp/timing/timeout/timeout_future.h
  30. +55
    -0
      include/asyncpp/timing/timeout/timeout_future.inl
  31. +50
    -0
      include/asyncpp/timing/timeout/timeout_stream.h
  32. +60
    -0
      include/asyncpp/timing/timeout/timeout_stream.inl
  33. +9
    -48
      include/asyncpp/timing/timer.h
  34. +4
    -4
      include/asyncpp/timing/timer/resource.h
  35. +3
    -3
      include/asyncpp/timing/timer/resource.inl
  36. +44
    -0
      include/asyncpp/timing/timer/timer.h
  37. +6
    -12
      include/asyncpp/timing/timer/timer.inl
  38. +87
    -0
      include/asyncpp/timing/timer/timer_base.h
  39. +83
    -0
      include/asyncpp/timing/timer/timer_base.inl
  40. +0
    -0
      include/asyncpp/timing/timer/timer_base.pre.h
  41. +10
    -0
      include/asyncpp/timing/timer/timer_impl.h
  42. +76
    -0
      include/asyncpp/timing/timer/timer_impl.inl
  43. +6
    -0
      src/CMakeLists.txt
  44. +1
    -2
      test/asyncpp/executor/current_thread_tests.cpp
  45. +1
    -2
      test/asyncpp/timing/delay_tests.cpp
  46. +1
    -2
      test/asyncpp/timing/interval_tests.cpp
  47. +8
    -9
      test/asyncpp/timing/timeout_tests.cpp
  48. +5
    -14
      test/asyncpp/timing/timer_tests.cpp

+ 3
- 0
cmake/asyncpp-options.cmake Dosyayı Görüntüle

@@ -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 )

+ 3
- 0
cmake/config.h.in Dosyayı Görüntüle

@@ -0,0 +1,3 @@
#pragma once

#cmakedefine ASYNCPP_FEATURE_TIMING_ENABLED

+ 6
- 0
include/asyncpp.h Dosyayı Görüntüle

@@ -1,3 +1,9 @@
#pragma once

#include <asyncpp/config.h>

#include <asyncpp/core.h>

#ifdef ASYNCPP_FEATURE_TIMING_ENABLED
#include <asyncpp/timing.h>
#endif

+ 1
- 1
include/asyncpp/core/future.h Dosyayı Görüntüle

@@ -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

+ 1
- 1
include/asyncpp/core/future/future.h Dosyayı Görüntüle

@@ -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.


+ 4
- 2
include/asyncpp/core/future/timeout.inl Dosyayı Görüntüle

@@ -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);
}


+ 1
- 1
include/asyncpp/core/stream.h Dosyayı Görüntüle

@@ -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

+ 1
- 1
include/asyncpp/core/stream/stream.h Dosyayı Görüntüle

@@ -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.


+ 4
- 2
include/asyncpp/core/stream/timeout.inl Dosyayı Görüntüle

@@ -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);
}


+ 3
- 0
include/asyncpp/core/task/task.h Dosyayı Görüntüle

@@ -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.
*/


+ 8
- 1
include/asyncpp/core/task/task.inl Dosyayı Görüntüle

@@ -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(); }


+ 8
- 1
include/asyncpp/executor/executor.inl Dosyayı Görüntüle

@@ -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
- 6
include/asyncpp/timing.h Dosyayı Görüntüle

@@ -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"

+ 2
- 61
include/asyncpp/timing/delay.h Dosyayı Görüntüle

@@ -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"

+ 65
- 0
include/asyncpp/timing/delay/delay.h Dosyayı Görüntüle

@@ -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();
};

} }

include/asyncpp/timing/delay.inl → include/asyncpp/timing/delay/delay.inl Dosyayı Görüntüle

@@ -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();
}

include/asyncpp/timing/delay.pre.h → include/asyncpp/timing/delay/delay.pre.h Dosyayı Görüntüle


+ 0
- 88
include/asyncpp/timing/impl/timer_base.h Dosyayı Görüntüle

@@ -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();
};

} } }

+ 0
- 91
include/asyncpp/timing/impl/timer_base.inl Dosyayı Görüntüle

@@ -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;
}

} } }

+ 0
- 80
include/asyncpp/timing/impl/timer_impl.h Dosyayı Görüntüle

@@ -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();
};

}

} }

+ 0
- 73
include/asyncpp/timing/impl/timer_impl.inl Dosyayı Görüntüle

@@ -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>(); }

} } }

+ 2
- 52
include/asyncpp/timing/interval.h Dosyayı Görüntüle

@@ -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"

+ 55
- 0
include/asyncpp/timing/interval/interval.h Dosyayı Görüntüle

@@ -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();
};

} }

include/asyncpp/timing/interval.inl → include/asyncpp/timing/interval/interval.inl Dosyayı Görüntüle

@@ -2,7 +2,7 @@

#include "interval.h"

#include "delay.inl"
#include "../delay/delay.inl"

namespace asyncpp {
namespace timing {

+ 6
- 100
include/asyncpp/timing/timeout.h Dosyayı Görüntüle

@@ -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"

+ 0
- 96
include/asyncpp/timing/timeout.inl Dosyayı Görüntüle

@@ -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);
}

} }

+ 18
- 0
include/asyncpp/timing/timeout/misc.h Dosyayı Görüntüle

@@ -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();
};

} }

+ 14
- 0
include/asyncpp/timing/timeout/misc.inl Dosyayı Görüntüle

@@ -0,0 +1,14 @@
#pragma once

#include "misc.h"

namespace asyncpp {
namespace timing {

/* timeout_exception */

timeout_exception::timeout_exception()
: cppcore::exception::exception("timeout")
{ }

} }

+ 50
- 0
include/asyncpp/timing/timeout/timeout_future.h Dosyayı Görüntüle

@@ -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();
};

} }

+ 55
- 0
include/asyncpp/timing/timeout/timeout_future.inl Dosyayı Görüntüle

@@ -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;
}

} }

+ 50
- 0
include/asyncpp/timing/timeout/timeout_stream.h Dosyayı Görüntüle

@@ -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();
};

} }

+ 60
- 0
include/asyncpp/timing/timeout/timeout_stream.inl Dosyayı Görüntüle

@@ -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;
}

} }

+ 9
- 48
include/asyncpp/timing/timer.h Dosyayı Görüntüle

@@ -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"

include/asyncpp/timing/impl/registration.h → include/asyncpp/timing/timer/resource.h Dosyayı Görüntüle

@@ -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>;

} } }

include/asyncpp/timing/impl/registration.inl → include/asyncpp/timing/timer/resource.inl Dosyayı Görüntüle

@@ -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)

+ 44
- 0
include/asyncpp/timing/timer/timer.h Dosyayı Görüntüle

@@ -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();
};

} }

include/asyncpp/timing/timer.inl → include/asyncpp/timing/timer/timer.inl Dosyayı Görüntüle

@@ -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(); }

} }

+ 87
- 0
include/asyncpp/timing/timer/timer_base.h Dosyayı Görüntüle

@@ -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();
};

} } }

+ 83
- 0
include/asyncpp/timing/timer/timer_base.inl Dosyayı Görüntüle

@@ -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;
}

} } }

include/asyncpp/timing/impl/timer_base.pre.h → include/asyncpp/timing/timer/timer_base.pre.h Dosyayı Görüntüle


+ 10
- 0
include/asyncpp/timing/timer/timer_impl.h Dosyayı Görüntüle

@@ -0,0 +1,10 @@
#pragma once

namespace asyncpp {
namespace timing {
namespace __impl {

template<typename T_inner>
struct timer_impl;

} } }

+ 76
- 0
include/asyncpp/timing/timer/timer_impl.inl Dosyayı Görüntüle

@@ -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); }
};

} } }

+ 6
- 0
src/CMakeLists.txt Dosyayı Görüntüle

@@ -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} )


+ 1
- 2
test/asyncpp/executor/current_thread_tests.cpp Dosyayı Görüntüle

@@ -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;


+ 1
- 2
test/asyncpp/timing/delay_tests.cpp Dosyayı Görüntüle

@@ -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)));


+ 1
- 2
test/asyncpp/timing/interval_tests.cpp Dosyayı Görüntüle

@@ -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))));


+ 8
- 9
test/asyncpp/timing/timeout_tests.cpp Dosyayı Görüntüle

@@ -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))));


+ 5
- 14
test/asyncpp/timing/timer_tests.cpp Dosyayı Görüntüle

@@ -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));


Yükleniyor…
İptal
Kaydet