|
|
@@ -0,0 +1,102 @@ |
|
|
|
#pragma once |
|
|
|
|
|
|
|
#include "timer.h" |
|
|
|
#include "delay.inl" |
|
|
|
|
|
|
|
namespace asyncpp { |
|
|
|
namespace timer { |
|
|
|
|
|
|
|
/* registration::inner */ |
|
|
|
|
|
|
|
registration::inner::inner(timer& p_owner, time_point p_timeout) |
|
|
|
: owner (p_owner) |
|
|
|
, timeout (p_timeout) |
|
|
|
{ } |
|
|
|
|
|
|
|
/* registration */ |
|
|
|
|
|
|
|
registration::registration(delay& p_owner) |
|
|
|
: owner(p_owner) |
|
|
|
, ptr () |
|
|
|
{ } |
|
|
|
|
|
|
|
/* timer::inner_less_compare */ |
|
|
|
|
|
|
|
constexpr bool timer::inner_less_compare::operator()(const inner_ptr_s& lhs, const inner_ptr_s& rhs) const |
|
|
|
{ |
|
|
|
return (lhs->timeout < rhs->timeout) |
|
|
|
? true |
|
|
|
: |
|
|
|
(lhs->timeout == rhs->timeout) |
|
|
|
&& (lhs.get() < rhs.get()) |
|
|
|
? true |
|
|
|
: false; |
|
|
|
} |
|
|
|
|
|
|
|
/* timer */ |
|
|
|
|
|
|
|
size_t timer::resource_count() const |
|
|
|
{ return _registrations.size(); } |
|
|
|
|
|
|
|
void timer::make_current() |
|
|
|
{ |
|
|
|
auto& s = local_storage(); |
|
|
|
if (s.current) |
|
|
|
throw std::runtime_error("Thread local timer instance is already assigned!"); |
|
|
|
s.current = this; |
|
|
|
} |
|
|
|
|
|
|
|
void timer::clear_current() |
|
|
|
{ |
|
|
|
auto& s = local_storage(); |
|
|
|
if (s.current && s.current != this) |
|
|
|
throw std::runtime_error("Thread local timer instance is not assigned to this instance!"); |
|
|
|
s.current = nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
timer* timer::current() |
|
|
|
{ return local_storage().current; } |
|
|
|
|
|
|
|
void timer::register_resource(registration& p_value) |
|
|
|
{ |
|
|
|
auto s = p_value.ptr.lock(); |
|
|
|
|
|
|
|
if (s && s->timeout != p_value.owner.timeout()) |
|
|
|
{ |
|
|
|
unregister_resource(p_value); |
|
|
|
s.reset(); |
|
|
|
} |
|
|
|
|
|
|
|
if (!s) |
|
|
|
{ |
|
|
|
auto t = current(); |
|
|
|
|
|
|
|
if (!t) |
|
|
|
throw std::runtime_error("Thread local timer instance is not assigned!"); |
|
|
|
|
|
|
|
p_value.ptr = t->make_inner(p_value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void timer::unregister_resource(registration& p_value) |
|
|
|
{ |
|
|
|
auto s = p_value.ptr.lock(); |
|
|
|
p_value.ptr.reset(); |
|
|
|
if (s) |
|
|
|
s->owner._registrations.erase(s); |
|
|
|
} |
|
|
|
|
|
|
|
inline timer::inner_ptr_s timer::make_inner(registration& p_value) |
|
|
|
{ |
|
|
|
auto s = std::make_shared<registration::inner>(*this, p_value.owner.timeout()); |
|
|
|
_registrations.insert(s); |
|
|
|
return s; |
|
|
|
} |
|
|
|
|
|
|
|
timer::storage& timer::local_storage() |
|
|
|
{ |
|
|
|
thread_local storage value; |
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
} } |