summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWilliam A. Kennington III <wak@google.com>2018-07-17 14:40:14 -0700
committerWilliam A. Kennington III <wak@google.com>2018-07-17 14:40:14 -0700
commit48c427510b0fd9ead21978f8e20f7394c95fde8d (patch)
tree72c7d98f537f73be1dceee344fdf2114c9b5b2e3 /src
parent65db863e625b04e2094849702eca8a63958f6279 (diff)
downloadsdeventplus-48c427510b0fd9ead21978f8e20f7394c95fde8d.tar.gz
sdeventplus-48c427510b0fd9ead21978f8e20f7394c95fde8d.zip
source/base: Add the prepare callback functionality
Diffstat (limited to 'src')
-rw-r--r--src/sdeventplus/internal/sdevent.hpp8
-rw-r--r--src/sdeventplus/source/base.cpp47
-rw-r--r--src/sdeventplus/source/base.hpp9
3 files changed, 64 insertions, 0 deletions
diff --git a/src/sdeventplus/internal/sdevent.hpp b/src/sdeventplus/internal/sdevent.hpp
index e6c420c..dfb6285 100644
--- a/src/sdeventplus/internal/sdevent.hpp
+++ b/src/sdeventplus/internal/sdevent.hpp
@@ -32,6 +32,9 @@ class SdEvent
virtual int
sd_event_source_set_description(sd_event_source* source,
const char* description) const = 0;
+ virtual int
+ sd_event_source_set_prepare(sd_event_source* source,
+ sd_event_handler_t callback) const = 0;
virtual int sd_event_source_get_pending(sd_event_source* source) const = 0;
virtual int sd_event_source_get_priority(sd_event_source* source,
int64_t* priority) const = 0;
@@ -101,6 +104,11 @@ class SdEventImpl : public SdEvent
{
return ::sd_event_source_set_description(source, description);
}
+ int sd_event_source_set_prepare(sd_event_source* source,
+ sd_event_handler_t callback) const override
+ {
+ return ::sd_event_source_set_prepare(source, callback);
+ }
int sd_event_source_get_pending(sd_event_source* source) const override
{
return ::sd_event_source_get_pending(source);
diff --git a/src/sdeventplus/source/base.cpp b/src/sdeventplus/source/base.cpp
index d99d562..d361333 100644
--- a/src/sdeventplus/source/base.cpp
+++ b/src/sdeventplus/source/base.cpp
@@ -1,4 +1,5 @@
#include <cerrno>
+#include <cstdio>
#include <exception>
#include <sdeventplus/exception.hpp>
#include <sdeventplus/internal/sdevent.hpp>
@@ -17,6 +18,30 @@ Base::~Base()
set_enabled(SD_EVENT_OFF);
}
+int Base::prepareCallback()
+{
+ try
+ {
+ prepare(*this);
+ return 0;
+ }
+ catch (const std::system_error& e)
+ {
+ fprintf(stderr, "sdeventplus: prepareCallback: %s\n", e.what());
+ return -e.code().value();
+ }
+ catch (const std::exception& e)
+ {
+ fprintf(stderr, "sdeventplus: prepareCallback: %s\n", e.what());
+ return -ENOSYS;
+ }
+ catch (...)
+ {
+ fprintf(stderr, "sdeventplus: prepareCallback: Unknown error\n");
+ return -ENOSYS;
+ }
+}
+
const char* Base::get_description()
{
const char* description;
@@ -38,6 +63,28 @@ void Base::set_description(const char* description)
}
}
+static int prepare_callback(sd_event_source*, void* userdata)
+{
+ if (userdata == nullptr)
+ {
+ fprintf(stderr, "sdeventplus: prepare_callback: Missing userdata\n");
+ return -EINVAL;
+ }
+ return reinterpret_cast<Base*>(userdata)->prepareCallback();
+}
+
+void Base::set_prepare(Callback&& callback)
+{
+ int r = sdevent->sd_event_source_set_prepare(
+ source.get(), callback ? prepare_callback : nullptr);
+ if (r < 0)
+ {
+ prepare = nullptr;
+ throw SdEventError(-r, "sd_event_source_set_prepare");
+ }
+ prepare = std::move(callback);
+}
+
int Base::get_pending()
{
int r = sdevent->sd_event_source_get_pending(source.get());
diff --git a/src/sdeventplus/source/base.hpp b/src/sdeventplus/source/base.hpp
index 20ab820..748f340 100644
--- a/src/sdeventplus/source/base.hpp
+++ b/src/sdeventplus/source/base.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
+#include <functional>
#include <sdeventplus/internal/sdevent.hpp>
#include <sdeventplus/internal/sdref.hpp>
#include <systemd/sd-bus.h>
@@ -14,6 +15,8 @@ namespace source
class Base
{
public:
+ using Callback = std::function<void(Base& source)>;
+
virtual ~Base();
// We don't want to allow any kind of slicing.
@@ -22,8 +25,11 @@ class Base
Base(Base&& source) = delete;
Base& operator=(Base&& source) = delete;
+ int prepareCallback();
+
const char* get_description();
void set_description(const char* description);
+ void set_prepare(Callback&& callback);
int get_pending();
int64_t get_priority();
void set_priority(int64_t priority);
@@ -39,6 +45,9 @@ class Base
internal::SdEvent* sdevent = &internal::sdevent_impl);
Base(sd_event_source* source, std::false_type,
internal::SdEvent* sdevent = &internal::sdevent_impl);
+
+ private:
+ Callback prepare;
};
} // namespace source
OpenPOWER on IntegriCloud