summaryrefslogtreecommitdiff
path: root/src/utils.hpp
diff options
context:
space:
mode:
authorPrzemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com>2022-03-15 00:20:54 +0300
committerGitHub <noreply@github.com>2022-03-15 00:20:54 +0300
commited2aceab6ee059a40d939ea21364bc18ec80d94b (patch)
tree654bbae1b29b9dcdc6e4ed0036dc5d70ad0544a5 /src/utils.hpp
parent1fb7beae5e97aadf8471ae7b6e07f5c2e5f33c78 (diff)
downloadvirtual-media-ed2aceab6ee059a40d939ea21364bc18ec80d94b.tar.xz
Make mount/unmount dbus calls asynchronous
Change the default behavior of mount/umount dbus calls from blocking to unblocking ones. Once mount/unmount is triggered, appropriate action is running in the background moving handling of operation result to async event. At the end of processing dbus completion signal is sent to client with uint value of operation status (identical with errno code). Tested: Manual scheduling of mount and unmount operations with monitoring dbus communication of virtual-media service - matching api calls with completion signal. Signed-off-by: Przemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com>
Diffstat (limited to 'src/utils.hpp')
-rw-r--r--src/utils.hpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/utils.hpp b/src/utils.hpp
index 587cc41..db9f325 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -1,14 +1,19 @@
#pragma once
+#include "logger.hpp"
+
#include <unistd.h>
#include <algorithm>
+#include <boost/asio/steady_timer.hpp>
#include <boost/process/async_pipe.hpp>
#include <boost/type_traits/has_dereference.hpp>
#include <filesystem>
#include <memory>
+#include <optional>
#include <sdbusplus/asio/object_server.hpp>
#include <string>
+#include <system_error>
#include <vector>
namespace fs = std::filesystem;
@@ -281,4 +286,80 @@ class VolatileFile
std::string filePath;
const std::size_t size;
};
+
+class SignalSender
+{
+ public:
+ SignalSender(std::shared_ptr<sdbusplus::asio::connection> con,
+ const std::string& obj, const std::string& iface,
+ const std::string& name) :
+ con(con),
+ interface(iface), object(obj), name(name){};
+
+ SignalSender() = delete;
+ SignalSender(const SignalSender&) = delete;
+
+ void send(std::optional<const std::error_code> status)
+ {
+ auto msgSignal =
+ con->new_signal(object.c_str(), interface.c_str(), name.c_str());
+
+ msgSignal.append(status.value_or(std::error_code{}).value());
+ LogMsg(Logger::Debug, "Sending signal: Object: ", object,
+ ", Interface: ", interface, ", Name: ", name,
+ "Status: ", status.value_or(std::error_code{}).value());
+ msgSignal.signal_send();
+ }
+
+ private:
+ std::shared_ptr<sdbusplus::asio::connection> con;
+ std::string interface;
+ std::string object;
+ std::string name;
+};
+
+class NotificationWrapper
+{
+ public:
+ NotificationWrapper(std::unique_ptr<SignalSender> signal,
+ std::unique_ptr<boost::asio::steady_timer> timer) :
+ signal(std::move(signal)),
+ timer(std::move(timer))
+ {
+ }
+
+ void start(std::function<void(const boost::system::error_code&)>&& handler,
+ const std::chrono::seconds& duration)
+ {
+ LogMsg(Logger::Debug, "Notification initiated");
+ started = true;
+ timer->expires_from_now(duration);
+ timer->async_wait([this, handler{std::move(handler)}](
+ const boost::system::error_code& ec) {
+ started = false;
+ handler(ec);
+ });
+ }
+
+ void notify(const std::error_code& ec)
+ {
+ if (started)
+ {
+ timer->cancel();
+ if (ec)
+ signal->send((ec));
+ else
+ signal->send(std::nullopt);
+ started = false;
+ return;
+ }
+ LogMsg(Logger::Debug, "Notification(ec) supressed (not started)");
+ }
+
+ private:
+ std::unique_ptr<SignalSender> signal;
+ std::unique_ptr<boost::asio::steady_timer> timer;
+ bool started{false};
+};
+
} // namespace utils