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 | 8f90e28b500d384fbabcf97119879c7ba3c88724 (patch) | |
| tree | 8c68ef24d7b8ec3e36b8c3d793d4dd3fe763b030 /src | |
| download | sdeventplus-8f90e28b500d384fbabcf97119879c7ba3c88724.tar.gz sdeventplus-8f90e28b500d384fbabcf97119879c7ba3c88724.zip | |
Initial Commit
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 22 | ||||
| -rw-r--r-- | src/sdeventplus.pc.in | 11 | ||||
| -rw-r--r-- | src/sdeventplus/event.cpp | 53 | ||||
| -rw-r--r-- | src/sdeventplus/event.hpp | 27 | ||||
| -rw-r--r-- | src/sdeventplus/exception.cpp | 12 | ||||
| -rw-r--r-- | src/sdeventplus/exception.hpp | 14 | ||||
| -rw-r--r-- | src/sdeventplus/sdevent.cpp | 6 | ||||
| -rw-r--r-- | src/sdeventplus/sdevent.hpp | 52 | ||||
| -rw-r--r-- | src/sdeventplus/sdref.hpp | 89 | ||||
| -rw-r--r-- | src/sdeventplus/test/sdevent.hpp | 21 |
10 files changed, 307 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..5379c0a --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,22 @@ +AM_CPPFLAGS = $(SYSTEMD_CFLAGS) $(CODE_COVERAGE_CPPFLAGS) +AM_CFLAGS = $(CODE_COVERAGE_CFLAGS) +AM_CXXFLAGS = $(CODE_COVERAGE_CXXFLAGS) + +nobase_include_HEADERS = +pkgconfig_DATA = sdeventplus.pc +lib_LTLIBRARIES = libsdeventplus.la +libsdeventplus_la_SOURCES = +libsdeventplus_la_LIBADD = $(SYSTEMD_LIBS) $(CODE_COVERAGE_LIBS) + +nobase_include_HEADERS += sdeventplus/event.hpp +libsdeventplus_la_SOURCES += sdeventplus/event.cpp + +nobase_include_HEADERS += sdeventplus/exception.hpp +libsdeventplus_la_SOURCES += sdeventplus/exception.cpp + +nobase_include_HEADERS += sdeventplus/sdevent.hpp +libsdeventplus_la_SOURCES += sdeventplus/sdevent.cpp + +nobase_include_HEADERS += sdeventplus/sdref.hpp + +nobase_include_HEADERS += sdeventplus/test/sdevent.hpp diff --git a/src/sdeventplus.pc.in b/src/sdeventplus.pc.in new file mode 100644 index 0000000..3d67d40 --- /dev/null +++ b/src/sdeventplus.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: sdeventplus +Version: @VERSION@ +Requires: @AX_PACKAGE_REQUIRES@ +Requires.private: @AX_PACKAGE_REQUIRES_PRIVATE@ +Cflags: -I${includedir} +Libs: -L${libdir} -lsdeventplus diff --git a/src/sdeventplus/event.cpp b/src/sdeventplus/event.cpp new file mode 100644 index 0000000..1baca16 --- /dev/null +++ b/src/sdeventplus/event.cpp @@ -0,0 +1,53 @@ +#include <functional> +#include <sdeventplus/event.hpp> +#include <sdeventplus/exception.hpp> + +namespace sdeventplus +{ + +Event::Event(sd_event* event, SdEventInterface* intf) : + intf(intf), event(event, &SdEventInterface::sd_event_ref, + &SdEventInterface::sd_event_unref, intf) +{ +} + +Event::Event(sd_event* event, std::false_type, SdEventInterface* intf) : + intf(intf), + event(event, &SdEventInterface::sd_event_ref, + &SdEventInterface::sd_event_unref, std::false_type(), intf) +{ +} + +Event Event::get_new(SdEventInterface* intf) +{ + sd_event* event = nullptr; + int r = intf->sd_event_new(&event); + if (r < 0) + { + throw SdEventError(-r, "sd_event_new"); + } + return Event(event, std::false_type(), intf); +} + +Event Event::get_default(SdEventInterface* intf) +{ + sd_event* event = nullptr; + int r = intf->sd_event_default(&event); + if (r < 0) + { + throw SdEventError(-r, "sd_event_default"); + } + return Event(event, std::false_type(), intf); +} + +int Event::loop() +{ + int r = intf->sd_event_loop(event.get()); + if (r < 0) + { + throw SdEventError(-r, "sd_event_loop"); + } + return r; +} + +} // namespace sdeventplus diff --git a/src/sdeventplus/event.hpp b/src/sdeventplus/event.hpp new file mode 100644 index 0000000..e2372bb --- /dev/null +++ b/src/sdeventplus/event.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include <memory> +#include <sdeventplus/sdevent.hpp> +#include <sdeventplus/sdref.hpp> +#include <systemd/sd-event.h> + +namespace sdeventplus +{ + +class Event +{ + public: + Event(sd_event* event, SdEventInterface* intf = &sdevent_impl); + Event(sd_event* event, std::false_type, + SdEventInterface* intf = &sdevent_impl); + static Event get_new(SdEventInterface* intf = &sdevent_impl); + static Event get_default(SdEventInterface* intf = &sdevent_impl); + + int loop(); + + private: + SdEventInterface* intf; + SdRef<sd_event> event; +}; + +} // namespace sdeventplus diff --git a/src/sdeventplus/exception.cpp b/src/sdeventplus/exception.cpp new file mode 100644 index 0000000..1cfba4f --- /dev/null +++ b/src/sdeventplus/exception.cpp @@ -0,0 +1,12 @@ +#include <sdeventplus/exception.hpp> +#include <system_error> + +namespace sdeventplus +{ + +SdEventError::SdEventError(int r, const char *prefix) : + std::system_error(r, std::generic_category(), prefix) +{ +} + +} // namespace sdeventplus diff --git a/src/sdeventplus/exception.hpp b/src/sdeventplus/exception.hpp new file mode 100644 index 0000000..eb88649 --- /dev/null +++ b/src/sdeventplus/exception.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include <system_error> + +namespace sdeventplus +{ + +class SdEventError final : public std::system_error +{ + public: + SdEventError(int r, const char *prefix); +}; + +} // namespace sdeventplus diff --git a/src/sdeventplus/sdevent.cpp b/src/sdeventplus/sdevent.cpp new file mode 100644 index 0000000..d145f38 --- /dev/null +++ b/src/sdeventplus/sdevent.cpp @@ -0,0 +1,6 @@ +#include <sdeventplus/sdevent.hpp> + +namespace sdeventplus +{ +SdEventImpl sdevent_impl; +} diff --git a/src/sdeventplus/sdevent.hpp b/src/sdeventplus/sdevent.hpp new file mode 100644 index 0000000..129e67f --- /dev/null +++ b/src/sdeventplus/sdevent.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include <systemd/sd-event.h> + +namespace sdeventplus +{ + +class SdEventInterface +{ + public: + virtual ~SdEventInterface() = default; + + virtual int sd_event_default(sd_event **event) const = 0; + virtual int sd_event_new(sd_event **event) const = 0; + 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_loop(sd_event *event) const = 0; +}; + +class SdEventImpl : public SdEventInterface +{ + public: + int sd_event_default(sd_event **event) const override + { + return ::sd_event_default(event); + } + + int sd_event_new(sd_event **event) const override + { + return ::sd_event_default(event); + } + + sd_event *sd_event_ref(sd_event *event) const override + { + return ::sd_event_ref(event); + } + + sd_event *sd_event_unref(sd_event *event) const override + { + return ::sd_event_unref(event); + } + + int sd_event_loop(sd_event *event) const override + { + return ::sd_event_loop(event); + } +}; + +extern SdEventImpl sdevent_impl; + +} // namespace sdeventplus diff --git a/src/sdeventplus/sdref.hpp b/src/sdeventplus/sdref.hpp new file mode 100644 index 0000000..492ae70 --- /dev/null +++ b/src/sdeventplus/sdref.hpp @@ -0,0 +1,89 @@ +#pragma once + +#include <functional> +#include <memory> +#include <sdeventplus/sdevent.hpp> +#include <type_traits> + +namespace sdeventplus +{ + +template <typename T> class SdRef +{ + public: + using Func = std::function<T*(SdEventInterface*, T*)>; + + SdRef(T* ref, Func take_ref, Func release_ref, + SdEventInterface* intf = sdevent_impl) : + SdRef(take_ref(intf, ref), take_ref, release_ref, std::false_type(), + intf) + { + } + + SdRef(T* ref, Func take_ref, Func release_ref, std::false_type, + SdEventInterface* intf = sdevent_impl) : + intf(intf), + take_ref(take_ref), release_ref(release_ref), ref(ref) + { + } + + SdRef(const SdRef& other) : + intf(other.intf), take_ref(other.take_ref), + release_ref(other.release_ref), ref(take_ref(intf, other.ref)) + { + } + + SdRef& operator=(const SdRef& other) + { + if (this != &other) + { + // release_ref will be invalid if moved + if (release_ref) + release_ref(intf, ref); + + intf = other.intf; + take_ref = other.take_ref; + release_ref = other.release_ref; + ref = take_ref(intf, other.ref); + } + return *this; + } + + SdRef(SdRef&& other) = default; + + SdRef& operator=(SdRef&& other) + { + if (this != &other) + { + // release_ref will be invalid if move + if (release_ref) + release_ref(intf, ref); + + intf = std::move(other.intf); + take_ref = std::move(other.take_ref); + release_ref = std::move(other.release_ref); + ref = std::move(other.ref); + } + return *this; + } + + virtual ~SdRef() + { + // release_ref will be invalid after a move + if (release_ref) + release_ref(intf, ref); + } + + T* get() const + { + return ref; + } + + private: + SdEventInterface* intf; + Func take_ref; + Func release_ref; + T* ref; +}; + +} // namespace sdeventplus diff --git a/src/sdeventplus/test/sdevent.hpp b/src/sdeventplus/test/sdevent.hpp new file mode 100644 index 0000000..b467647 --- /dev/null +++ b/src/sdeventplus/test/sdevent.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include <gmock/gmock.h> +#include <sdeventplus/sdevent.hpp> +#include <systemd/sd-event.h> + +namespace sdeventplus +{ + +class SdEventMock : public SdEventInterface +{ + public: + MOCK_CONST_METHOD1(sd_event_default, int(sd_event **)); + MOCK_CONST_METHOD1(sd_event_new, int(sd_event **)); + MOCK_CONST_METHOD1(sd_event_ref, sd_event *(sd_event *)); + MOCK_CONST_METHOD1(sd_event_unref, sd_event *(sd_event *)); + + MOCK_CONST_METHOD1(sd_event_loop, int(sd_event *)); +}; + +} // namespace sdeventplus |

