| @@ -19,7 +19,8 @@ namespace timer { | |||
| template<typename T_base, typename T_ratio> | |||
| delay::delay(const duration<T_base, T_ratio>& p_duration) | |||
| : _timeout(clock::now() + p_duration) | |||
| : _timeout (clock::now() + p_duration) | |||
| , _registration (*this) | |||
| { } | |||
| inline delay::~delay() | |||
| @@ -3,6 +3,8 @@ | |||
| #include <set> | |||
| #include <memory> | |||
| #include <cppcore/synchronization/locked.h> | |||
| #include "misc.h" | |||
| namespace asyncpp { | |||
| @@ -48,7 +50,13 @@ namespace timer { | |||
| using inner_set = std::set<inner_ptr_s, inner_less_compare>; | |||
| private: | |||
| inner_set _registrations; | |||
| cppcore::locked<inner_set> _registrations; | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| inline ~timer(); | |||
| public: | |||
| /** | |||
| @@ -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<registration::inner>(*this, p_value.owner.timeout()); | |||
| _registrations.insert(s); | |||
| _registrations.lock()->insert(s); | |||
| return s; | |||
| } | |||
| @@ -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 | |||
| $<BUILD_INTERFACE:${ASYNCPP_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${ASYNCPP_INSTALL_DIR_INCLUDE}> ) | |||
| Target_Link_Libraries ( asyncpp | |||
| INTERFACE | |||
| cppcore::cppcore ) | |||
| # Install ######################################################################################### | |||
| @@ -0,0 +1,78 @@ | |||
| #include <gtest/gtest.h> | |||
| #include "../../helper/now_mock.h" | |||
| #include <asyncpp.h> | |||
| #include <asyncpp/timer.h> | |||
| 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<now_mock> 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<delay_future_type>(timer::delay(std::chrono::seconds(10))); | |||
| auto f2 = std::make_unique<delay_future_type>(timer::delay(std::chrono::seconds(20))); | |||
| auto f3 = std::make_unique<delay_future_type>(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()); | |||
| } | |||