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-19 17:16:42 -0700 |
| commit | e32a88e1e3a587653c0edda9de26228305307274 (patch) | |
| tree | 586cd56f4fc8e86ff9b035dd843000ee9c7b753b /src | |
| parent | 15ac222458688558cf41d22c9abe5ae8e267299a (diff) | |
| download | sdeventplus-e32a88e1e3a587653c0edda9de26228305307274.tar.gz sdeventplus-e32a88e1e3a587653c0edda9de26228305307274.zip | |
source/time: Implement
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 3 | ||||
| -rw-r--r-- | src/sdeventplus/internal/sdevent.hpp | 47 | ||||
| -rw-r--r-- | src/sdeventplus/source/time.cpp | 106 | ||||
| -rw-r--r-- | src/sdeventplus/source/time.hpp | 43 | ||||
| -rw-r--r-- | src/sdeventplus/test/sdevent.hpp | 12 |
5 files changed, 211 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a027d5f..d4e7906 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,4 +24,7 @@ nobase_include_HEADERS += sdeventplus/internal/utils.hpp nobase_include_HEADERS += sdeventplus/source/base.hpp libsdeventplus_la_SOURCES += sdeventplus/source/base.cpp +nobase_include_HEADERS += sdeventplus/source/time.hpp +libsdeventplus_la_SOURCES += sdeventplus/source/time.cpp + nobase_include_HEADERS += sdeventplus/test/sdevent.hpp diff --git a/src/sdeventplus/internal/sdevent.hpp b/src/sdeventplus/internal/sdevent.hpp index 7713cb8..9a6ec07 100644 --- a/src/sdeventplus/internal/sdevent.hpp +++ b/src/sdeventplus/internal/sdevent.hpp @@ -17,6 +17,12 @@ class SdEvent virtual sd_event* sd_event_ref(sd_event* event) const = 0; virtual sd_event* sd_event_unref(sd_event* event) const = 0; + virtual int sd_event_add_time(sd_event* event, sd_event_source** source, + clockid_t clock, uint64_t usec, + uint64_t accuracy, + sd_event_time_handler_t callback, + void* userdata) const = 0; + virtual int sd_event_prepare(sd_event* event) const = 0; virtual int sd_event_wait(sd_event* event, uint64_t usec) const = 0; virtual int sd_event_dispatch(sd_event* event) const = 0; @@ -57,6 +63,14 @@ class SdEvent int* enabled) const = 0; virtual int sd_event_source_set_enabled(sd_event_source* source, int enabled) const = 0; + virtual int sd_event_source_get_time(sd_event_source* source, + uint64_t* usec) const = 0; + virtual int sd_event_source_set_time(sd_event_source* source, + uint64_t usec) const = 0; + virtual int sd_event_source_get_time_accuracy(sd_event_source* source, + uint64_t* usec) const = 0; + virtual int sd_event_source_set_time_accuracy(sd_event_source* source, + uint64_t usec) const = 0; }; class SdEventImpl : public SdEvent @@ -82,6 +96,15 @@ class SdEventImpl : public SdEvent return ::sd_event_unref(event); } + int sd_event_add_time(sd_event* event, sd_event_source** source, + clockid_t clock, uint64_t usec, uint64_t accuracy, + sd_event_time_handler_t callback, + void* userdata) const override + { + return ::sd_event_add_time(event, source, clock, usec, accuracy, + callback, userdata); + } + int sd_event_prepare(sd_event* event) const override { return ::sd_event_prepare(event); @@ -196,6 +219,30 @@ class SdEventImpl : public SdEvent { return ::sd_event_source_set_enabled(source, enabled); } + + int sd_event_source_get_time(sd_event_source* source, + uint64_t* usec) const override + { + return ::sd_event_source_get_time(source, usec); + } + + int sd_event_source_set_time(sd_event_source* source, + uint64_t usec) const override + { + return ::sd_event_source_set_time(source, usec); + } + + int sd_event_source_get_time_accuracy(sd_event_source* source, + uint64_t* usec) const override + { + return ::sd_event_source_get_time_accuracy(source, usec); + } + + int sd_event_source_set_time_accuracy(sd_event_source* source, + uint64_t usec) const override + { + return ::sd_event_source_set_time_accuracy(source, usec); + } }; extern SdEventImpl sdevent_impl; diff --git a/src/sdeventplus/source/time.cpp b/src/sdeventplus/source/time.cpp new file mode 100644 index 0000000..1a24604 --- /dev/null +++ b/src/sdeventplus/source/time.cpp @@ -0,0 +1,106 @@ +#include <cstdio> +#include <sdeventplus/clock.hpp> +#include <sdeventplus/exception.hpp> +#include <sdeventplus/internal/utils.hpp> +#include <sdeventplus/source/time.hpp> +#include <type_traits> +#include <utility> + +namespace sdeventplus +{ +namespace source +{ + +template <ClockId Id> +Time<Id>::Time(const Event& event, TimePoint time, Accuracy accuracy, + Callback&& callback) : + Base(event, create_source(event, time, accuracy), std::false_type()), + callback(std::move(callback)) +{ +} + +template <ClockId Id> +typename Time<Id>::TimePoint Time<Id>::get_time() const +{ + uint64_t usec; + int r = event.getSdEvent()->sd_event_source_get_time(source.get(), &usec); + if (r < 0) + { + throw SdEventError(-r, "sd_event_source_get_time"); + } + return Time<Id>::TimePoint(SdEventDuration(usec)); +} + +template <ClockId Id> +void Time<Id>::set_time(TimePoint time) const +{ + int r = event.getSdEvent()->sd_event_source_set_time( + source.get(), SdEventDuration(time.time_since_epoch()).count()); + if (r < 0) + { + throw SdEventError(-r, "sd_event_source_set_time"); + } +} + +template <ClockId Id> +typename Time<Id>::Accuracy Time<Id>::get_accuracy() const +{ + uint64_t usec; + int r = event.getSdEvent()->sd_event_source_get_time_accuracy(source.get(), + &usec); + if (r < 0) + { + throw SdEventError(-r, "sd_event_source_get_time_accuracy"); + } + return SdEventDuration(usec); +} + +template <ClockId Id> +void Time<Id>::set_accuracy(Accuracy accuracy) const +{ + int r = event.getSdEvent()->sd_event_source_set_time_accuracy( + source.get(), SdEventDuration(accuracy).count()); + if (r < 0) + { + throw SdEventError(-r, "sd_event_source_set_time_accuracy"); + } +} + +template <ClockId Id> +const typename Time<Id>::Callback& Time<Id>::get_callback() const +{ + return callback; +} + +template <ClockId Id> +sd_event_source* Time<Id>::create_source(const Event& event, TimePoint time, + Accuracy accuracy) +{ + sd_event_source* source; + int r = event.getSdEvent()->sd_event_add_time( + event.get(), &source, static_cast<clockid_t>(Id), + SdEventDuration(time.time_since_epoch()).count(), + SdEventDuration(accuracy).count(), timeCallback, nullptr); + if (r < 0) + { + throw SdEventError(-r, "sd_event_add_time"); + } + return source; +} + +template <ClockId Id> +int Time<Id>::timeCallback(sd_event_source* source, uint64_t usec, + void* userdata) +{ + return sourceCallback<Callback, Time, &Time::get_callback>( + "timeCallback", source, userdata, TimePoint(SdEventDuration(usec))); +} + +template class Time<ClockId::RealTime>; +template class Time<ClockId::Monotonic>; +template class Time<ClockId::BootTime>; +template class Time<ClockId::RealTimeAlarm>; +template class Time<ClockId::BootTimeAlarm>; + +} // namespace source +} // namespace sdeventplus diff --git a/src/sdeventplus/source/time.hpp b/src/sdeventplus/source/time.hpp new file mode 100644 index 0000000..28a42fb --- /dev/null +++ b/src/sdeventplus/source/time.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include <cstdint> +#include <functional> +#include <sdeventplus/clock.hpp> +#include <sdeventplus/internal/utils.hpp> +#include <sdeventplus/source/base.hpp> +#include <systemd/sd-event.h> + +namespace sdeventplus +{ +namespace source +{ + +template <ClockId Id> +class Time : public Base +{ + public: + using TimePoint = typename Clock<Id>::time_point; + using Accuracy = SdEventDuration; + using Callback = std::function<void(Time& source, TimePoint time)>; + + Time(const Event& event, TimePoint time, Accuracy accuracy, + Callback&& callback); + + TimePoint get_time() const; + void set_time(TimePoint time) const; + Accuracy get_accuracy() const; + void set_accuracy(Accuracy accuracy) const; + + private: + Callback callback; + + const Callback& get_callback() const; + + static sd_event_source* create_source(const Event& event, TimePoint time, + Accuracy accuracy); + static int timeCallback(sd_event_source* source, uint64_t usec, + void* userdata); +}; + +} // namespace source +} // namespace sdeventplus diff --git a/src/sdeventplus/test/sdevent.hpp b/src/sdeventplus/test/sdevent.hpp index 9b39d50..1e90bc7 100644 --- a/src/sdeventplus/test/sdevent.hpp +++ b/src/sdeventplus/test/sdevent.hpp @@ -17,6 +17,10 @@ class SdEventMock : public internal::SdEvent MOCK_CONST_METHOD1(sd_event_ref, sd_event*(sd_event*)); MOCK_CONST_METHOD1(sd_event_unref, sd_event*(sd_event*)); + MOCK_CONST_METHOD7(sd_event_add_time, + int(sd_event*, sd_event_source**, clockid_t, uint64_t, + uint64_t, sd_event_time_handler_t, void*)); + MOCK_CONST_METHOD1(sd_event_prepare, int(sd_event*)); MOCK_CONST_METHOD2(sd_event_wait, int(sd_event*, uint64_t)); MOCK_CONST_METHOD1(sd_event_dispatch, int(sd_event*)); @@ -51,6 +55,14 @@ class SdEventMock : public internal::SdEvent MOCK_CONST_METHOD2(sd_event_source_get_enabled, int(sd_event_source*, int*)); MOCK_CONST_METHOD2(sd_event_source_set_enabled, int(sd_event_source*, int)); + MOCK_CONST_METHOD2(sd_event_source_get_time, + int(sd_event_source*, uint64_t*)); + MOCK_CONST_METHOD2(sd_event_source_set_time, + int(sd_event_source*, uint64_t)); + MOCK_CONST_METHOD2(sd_event_source_get_time_accuracy, + int(sd_event_source*, uint64_t*)); + MOCK_CONST_METHOD2(sd_event_source_set_time_accuracy, + int(sd_event_source*, uint64_t)); }; } // namespace test |

