diff options
| author | William A. Kennington III <wak@google.com> | 2018-07-17 14:40:14 -0700 |
|---|---|---|
| committer | William A. Kennington III <wak@google.com> | 2018-07-17 14:40:14 -0700 |
| commit | 7597a081dc769aebc223deee0bcad604b670dbe6 (patch) | |
| tree | c2bb5b5908885ddc5ec6a787c04bd995a1142f2d | |
| parent | bdc59018d3d85af8c300bf62aecbac9610fd4f66 (diff) | |
| download | sdeventplus-7597a081dc769aebc223deee0bcad604b670dbe6.tar.gz sdeventplus-7597a081dc769aebc223deee0bcad604b670dbe6.zip | |
clock: Add class for future use
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | src/Makefile.am | 5 | ||||
| -rw-r--r-- | src/sdeventplus/clock.cpp | 38 | ||||
| -rw-r--r-- | src/sdeventplus/clock.hpp | 41 | ||||
| -rw-r--r-- | src/sdeventplus/internal/sdevent.hpp | 10 | ||||
| -rw-r--r-- | src/sdeventplus/internal/utils.hpp | 12 | ||||
| -rw-r--r-- | src/sdeventplus/test/sdevent.hpp | 3 | ||||
| -rw-r--r-- | test/Makefile.am | 5 | ||||
| -rw-r--r-- | test/clock.cpp | 58 |
9 files changed, 173 insertions, 0 deletions
@@ -42,6 +42,7 @@ Makefile.in # Output binaries /example/follow +/test/clock /test/event /test/exception /test/internal_sdref diff --git a/src/Makefile.am b/src/Makefile.am index 2943a2c..a027d5f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,6 +4,9 @@ lib_LTLIBRARIES = libsdeventplus.la libsdeventplus_la_SOURCES = libsdeventplus_la_LIBADD = $(COMMON_LIBS) +nobase_include_HEADERS += sdeventplus/clock.hpp +libsdeventplus_la_SOURCES += sdeventplus/clock.cpp + nobase_include_HEADERS += sdeventplus/event.hpp libsdeventplus_la_SOURCES += sdeventplus/event.cpp @@ -16,6 +19,8 @@ libsdeventplus_la_SOURCES += sdeventplus/internal/sdevent.cpp nobase_include_HEADERS += sdeventplus/internal/sdref.hpp libsdeventplus_la_SOURCES += sdeventplus/internal/sdref.cpp +nobase_include_HEADERS += sdeventplus/internal/utils.hpp + nobase_include_HEADERS += sdeventplus/source/base.hpp libsdeventplus_la_SOURCES += sdeventplus/source/base.cpp diff --git a/src/sdeventplus/clock.cpp b/src/sdeventplus/clock.cpp new file mode 100644 index 0000000..37395c4 --- /dev/null +++ b/src/sdeventplus/clock.cpp @@ -0,0 +1,38 @@ +#include <sdeventplus/clock.hpp> +#include <sdeventplus/exception.hpp> +#include <sdeventplus/internal/utils.hpp> +#include <utility> + +namespace sdeventplus +{ + +template <ClockId Id> +Clock<Id>::Clock(const Event& event) : event(event) +{ +} + +template <ClockId Id> +Clock<Id>::Clock(Event&& event) : event(std::move(event)) +{ +} + +template <ClockId Id> +typename Clock<Id>::time_point Clock<Id>::now() const +{ + uint64_t now; + int r = event.getSdEvent()->sd_event_now(event.get(), + static_cast<clockid_t>(Id), &now); + if (r < 0) + { + throw SdEventError(-r, "sd_event_now"); + } + return time_point(SdEventDuration(now)); +} + +template class Clock<ClockId::RealTime>; +template class Clock<ClockId::Monotonic>; +template class Clock<ClockId::BootTime>; +template class Clock<ClockId::RealTimeAlarm>; +template class Clock<ClockId::BootTimeAlarm>; + +} // namespace sdeventplus diff --git a/src/sdeventplus/clock.hpp b/src/sdeventplus/clock.hpp new file mode 100644 index 0000000..c59d721 --- /dev/null +++ b/src/sdeventplus/clock.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include <chrono> +#include <cstdint> +#include <ctime> +#include <sdeventplus/event.hpp> +#include <sdeventplus/internal/utils.hpp> +#include <type_traits> + +namespace sdeventplus +{ + +enum class ClockId : clockid_t +{ + RealTime = CLOCK_REALTIME, + Monotonic = CLOCK_MONOTONIC, + BootTime = CLOCK_BOOTTIME, + RealTimeAlarm = CLOCK_REALTIME_ALARM, + BootTimeAlarm = CLOCK_BOOTTIME_ALARM, +}; + +template <ClockId Id> +class Clock +{ + public: + using rep = SdEventDuration::rep; + using period = SdEventDuration::period; + using duration = SdEventDuration; + using time_point = std::chrono::time_point<Clock>; + static constexpr bool is_steady = Id == ClockId::Monotonic; + + Clock(const Event& event); + Clock(Event&& event); + + time_point now() const; + + private: + const Event event; +}; + +} // namespace sdeventplus diff --git a/src/sdeventplus/internal/sdevent.hpp b/src/sdeventplus/internal/sdevent.hpp index a3672d1..4baff05 100644 --- a/src/sdeventplus/internal/sdevent.hpp +++ b/src/sdeventplus/internal/sdevent.hpp @@ -18,6 +18,10 @@ class SdEvent virtual sd_event* sd_event_unref(sd_event* event) const = 0; virtual int sd_event_loop(sd_event* event) const = 0; + + virtual int sd_event_now(sd_event* event, clockid_t clock, + uint64_t* usec) const = 0; + virtual int sd_event_get_watchdog(sd_event* event) const = 0; virtual int sd_event_set_watchdog(sd_event* event, int b) const = 0; @@ -74,6 +78,12 @@ class SdEventImpl : public SdEvent return ::sd_event_loop(event); } + int sd_event_now(sd_event* event, clockid_t clock, + uint64_t* usec) const override + { + return ::sd_event_now(event, clock, usec); + } + int sd_event_get_watchdog(sd_event* event) const override { return ::sd_event_get_watchdog(event); diff --git a/src/sdeventplus/internal/utils.hpp b/src/sdeventplus/internal/utils.hpp new file mode 100644 index 0000000..253e10d --- /dev/null +++ b/src/sdeventplus/internal/utils.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include <chrono> + +namespace sdeventplus +{ + +// Defined by systemd taking uint64_t usec params +using SdEventDuration = + std::chrono::duration<uint64_t, std::chrono::microseconds::period>; + +} // namespace sdeventplus diff --git a/src/sdeventplus/test/sdevent.hpp b/src/sdeventplus/test/sdevent.hpp index 1cb723f..5f0e400 100644 --- a/src/sdeventplus/test/sdevent.hpp +++ b/src/sdeventplus/test/sdevent.hpp @@ -18,6 +18,9 @@ class SdEventMock : public internal::SdEvent MOCK_CONST_METHOD1(sd_event_unref, sd_event*(sd_event*)); MOCK_CONST_METHOD1(sd_event_loop, int(sd_event*)); + + MOCK_CONST_METHOD3(sd_event_now, int(sd_event*, clockid_t, uint64_t*)); + MOCK_CONST_METHOD1(sd_event_get_watchdog, int(sd_event*)); MOCK_CONST_METHOD2(sd_event_set_watchdog, int(sd_event*, int b)); diff --git a/test/Makefile.am b/test/Makefile.am index 1b4ee1e..d1923fa 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -7,6 +7,11 @@ gtest_ldadd = $(SDEVENTPLUS_LIBS) $(GTEST_LIBS) $(GMOCK_LIBS) -lgmock_main check_PROGRAMS = TESTS = $(check_PROGRAMS) +check_PROGRAMS += clock +clock_SOURCES = clock.cpp +clock_CPPFLAGS = $(gtest_cppflags) +clock_LDADD = $(gtest_ldadd) + check_PROGRAMS += event event_SOURCES = event.cpp event_CPPFLAGS = $(gtest_cppflags) diff --git a/test/clock.cpp b/test/clock.cpp new file mode 100644 index 0000000..e004341 --- /dev/null +++ b/test/clock.cpp @@ -0,0 +1,58 @@ +#include <cerrno> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <sdeventplus/clock.hpp> +#include <sdeventplus/event.hpp> +#include <sdeventplus/exception.hpp> +#include <sdeventplus/test/sdevent.hpp> +#include <systemd/sd-event.h> +#include <type_traits> +#include <utility> + +namespace sdeventplus +{ +namespace +{ + +using testing::DoAll; +using testing::Return; +using testing::SetArgPointee; + +class ClockTest : public testing::Test +{ + protected: + testing::StrictMock<test::SdEventMock> mock; + sd_event* const expected_event = reinterpret_cast<sd_event*>(1234); +}; + +TEST_F(ClockTest, CopyEvent) +{ + Event event(expected_event, std::false_type(), &mock); + + EXPECT_CALL(mock, sd_event_ref(expected_event)) + .WillOnce(Return(expected_event)); + Clock<ClockId::RealTime> clock(event); + EXPECT_CALL(mock, sd_event_now(expected_event, CLOCK_REALTIME, testing::_)) + .WillOnce(DoAll(SetArgPointee<2>(2000000), Return(0))); + EXPECT_EQ(Clock<ClockId::RealTime>::time_point(std::chrono::seconds{2}), + clock.now()); + + EXPECT_CALL(mock, sd_event_unref(expected_event)) + .Times(2) + .WillRepeatedly(Return(nullptr)); +} + +TEST_F(ClockTest, MoveEvent) +{ + Event event(expected_event, std::false_type(), &mock); + + Clock<ClockId::Monotonic> clock(std::move(event)); + EXPECT_CALL(mock, sd_event_now(expected_event, CLOCK_MONOTONIC, testing::_)) + .WillOnce(Return(-EINVAL)); + EXPECT_THROW(clock.now(), SdEventError); + + EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr)); +} + +} // namespace +} // namespace sdeventplus |

