diff --git a/include/asyncpp/timer/delay.inl b/include/asyncpp/timer/delay.inl index 3bbd614..e5c2741 100644 --- a/include/asyncpp/timer/delay.inl +++ b/include/asyncpp/timer/delay.inl @@ -19,7 +19,8 @@ namespace timer { template delay::delay(const duration& p_duration) - : _timeout(clock::now() + p_duration) + : _timeout (clock::now() + p_duration) + , _registration (*this) { } inline delay::~delay() diff --git a/include/asyncpp/timer/timer.h b/include/asyncpp/timer/timer.h index 17ebb1f..77c1e4a 100644 --- a/include/asyncpp/timer/timer.h +++ b/include/asyncpp/timer/timer.h @@ -3,6 +3,8 @@ #include #include +#include + #include "misc.h" namespace asyncpp { @@ -48,7 +50,13 @@ namespace timer { using inner_set = std::set; private: - inner_set _registrations; + cppcore::locked _registrations; + + public: + /** + * @brief Constructor. + */ + inline ~timer(); public: /** diff --git a/include/asyncpp/timer/timer.inl b/include/asyncpp/timer/timer.inl index fd51be9..65def8d 100644 --- a/include/asyncpp/timer/timer.inl +++ b/include/asyncpp/timer/timer.inl @@ -35,8 +35,15 @@ namespace timer { /* timer */ + timer::~timer() + { + auto& s = local_storage(); + if (s.current == this) + s.current = nullptr; + } + size_t timer::resource_count() const - { return _registrations.size(); } + { return _registrations.lock()->size(); } void timer::make_current() { @@ -83,13 +90,13 @@ namespace timer { auto s = p_value.ptr.lock(); p_value.ptr.reset(); if (s) - s->owner._registrations.erase(s); + s->owner._registrations.lock()->erase(s); } inline timer::inner_ptr_s timer::make_inner(registration& p_value) { auto s = std::make_shared(*this, p_value.owner.timeout()); - _registrations.insert(s); + _registrations.lock()->insert(s); return s; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6c607fc..afd6aa9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,8 @@ Include ( cotire OPTIONAL RESULT_VARIABLE HAS Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC ) Include ( strip_symbols OPTIONAL RESULT_VARIABLE HAS_STRIP_SYMBOLS ) +Find_Package ( cppcore REQUIRED ) + # Interface Library ############################################################################### Set ( ASYNCPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include ) @@ -12,6 +14,9 @@ Target_Include_Directories ( asyncpp INTERFACE $ $ ) +Target_Link_Libraries ( asyncpp + INTERFACE + cppcore::cppcore ) # Install ######################################################################################### diff --git a/test/asyncpp/timer/timer_tests.cpp b/test/asyncpp/timer/timer_tests.cpp new file mode 100644 index 0000000..1c3279d --- /dev/null +++ b/test/asyncpp/timer/timer_tests.cpp @@ -0,0 +1,78 @@ +#include + +#include "../../helper/now_mock.h" + +#include +#include + +using namespace ::testing; +using namespace ::asyncpp; + +TEST(timer_tests, current) +{ + { + timer::timer t; + + EXPECT_EQ(nullptr, timer::timer::current()); + + t.make_current(); + + EXPECT_EQ(&t, timer::timer::current()); + + t.clear_current(); + + EXPECT_EQ(nullptr, timer::timer::current()); + + t.make_current(); + + EXPECT_EQ(&t, timer::timer::current()); + } + + EXPECT_EQ(nullptr, timer::timer::current()); +} + +TEST(timer_tests, resource_registration) +{ + StrictMock m; + EXPECT_CALL(m, now) + .WillRepeatedly(Return(timer::time_point(std::chrono::seconds(0)))); + + using delay_future_type = decltype(as_future(timer::delay(std::chrono::seconds(10)))); + + timer::timer t; + t.make_current(); + + auto f1 = std::make_unique(timer::delay(std::chrono::seconds(10))); + auto f2 = std::make_unique(timer::delay(std::chrono::seconds(20))); + auto f3 = std::make_unique(timer::delay(std::chrono::seconds(30))); + + EXPECT_EQ(0, t.resource_count()); + + f1->poll(); // simple add + + EXPECT_EQ(1, t.resource_count()); + + f2->poll(); // simple add + + EXPECT_EQ(2, t.resource_count()); + + f1.reset(); // remove first + + EXPECT_EQ(1, t.resource_count()); + + f3->poll(); // simple add + + EXPECT_EQ(2, t.resource_count()); + + f3->poll(); // calling twice should not add + + EXPECT_EQ(2, t.resource_count()); + + f3.reset(); // remove last + + EXPECT_EQ(1, t.resource_count()); + + f2.reset(); // remove remaining + + EXPECT_EQ(0, t.resource_count()); +}