From efa2eb9e58553c9e980aac98a0a30f2d8a30dc1c Mon Sep 17 00:00:00 2001
From: Benny Baumann <BenBE@geshi.org>
Date: Wed, 30 Dec 2020 15:33:41 +0100
Subject: [PATCH] Split libev interface into separate modules

---
 src/app/mumta.cpp    | 32 +++++---------------------------
 src/lib/ev/ev.cpp    | 38 ++++++++++++++++++++++++++++++++++++++
 src/lib/ev/ev.hpp    |  3 +++
 src/mumta/evloop.cpp | 36 ++++++++++++++++++++++++++++++++++++
 src/mumta/evloop.hpp | 16 ++++++++++++++++
 5 files changed, 98 insertions(+), 27 deletions(-)
 create mode 100644 src/lib/ev/ev.cpp
 create mode 100644 src/lib/ev/ev.hpp
 create mode 100644 src/mumta/evloop.cpp
 create mode 100644 src/mumta/evloop.hpp

diff --git a/src/app/mumta.cpp b/src/app/mumta.cpp
index 296e09a..002e811 100644
--- a/src/app/mumta.cpp
+++ b/src/app/mumta.cpp
@@ -3,31 +3,11 @@
 #include <iostream>
 #include <thread>
 
-#include <ev++.h>
+#include "lib/ev/ev.hpp"
 
-#include "service/daemonctl.hpp"
-
-bool check_version_libev() {
-    auto ev_major{ev::version_major()};
-    auto ev_minor{ev::version_minor()};
-
-    constexpr auto exp_major{EV_VERSION_MAJOR};
-    constexpr auto exp_minor{EV_VERSION_MINOR};
-
-    std::cout << "Checking dependency: libev: detected " << ev_major << "." << ev_minor << ", compiled " << exp_major << "." << exp_minor << "\n" << std::flush;
-
-    if(ev_major != exp_major) {
-        std::cerr << "Checking dependency: libev: failed version check: Major API version mismatch.\n" << std::flush;
-        return false;
-    }
+#include "mumta/evloop.hpp"
 
-    if(ev_minor < exp_minor) {
-        std::cerr << "Checking dependency: libev: failed version check: Minor API version too old.\n" << std::flush;
-        return false;
-    }
-
-    return true;
-}
+#include "service/daemonctl.hpp"
 
 int main() {
     dctl_status_msg("Checking environment");
@@ -48,10 +28,8 @@ int main() {
     dctl_status_ready();
     dctl_status_msg("Active");
 
-    for(size_t x = 10; x; x--) {
-        std::this_thread::sleep_for(std::chrono::seconds(1));
-        dctl_watchdog_refresh();
-    }
+    dctl_watchdog_refresh();
+    rmrf::ev::loop();
 
     dctl_status_msg("Preparing for shutdown");
     dctl_status_shutdown();
diff --git a/src/lib/ev/ev.cpp b/src/lib/ev/ev.cpp
new file mode 100644
index 0000000..aebd5b9
--- /dev/null
+++ b/src/lib/ev/ev.cpp
@@ -0,0 +1,38 @@
+#include "lib/ev/ev.hpp"
+
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include <ev++.h>
+
+#include "service/daemonctl.hpp"
+
+bool check_version_libev()
+{
+    auto ev_major{ev::version_major()};
+    auto ev_minor{ev::version_minor()};
+
+    constexpr auto exp_major{EV_VERSION_MAJOR};
+    constexpr auto exp_minor{EV_VERSION_MINOR};
+
+    std::stringstream str;
+    str <<
+        "Checking dependency: libev: detected " <<
+        std::dec << ev_major << "." << std::setw(2) << std::setfill('0') << ev_minor <<
+        ", compiled " <<
+        std::dec << exp_major << "." << std::setw(2) << std::setfill('0') << exp_minor;
+    dctl_status_msg(str.str().c_str());
+
+    if (ev_major != exp_major) {
+        dctl_status_err("Checking dependency: libev: failed version check: Major API version mismatch.\n");
+        return false;
+    }
+
+    if (ev_minor < exp_minor) {
+        dctl_status_err("Checking dependency: libev: failed version check: Minor API version too old.\n");
+        return false;
+    }
+
+    return true;
+}
diff --git a/src/lib/ev/ev.hpp b/src/lib/ev/ev.hpp
new file mode 100644
index 0000000..6ee9d46
--- /dev/null
+++ b/src/lib/ev/ev.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+bool check_version_libev();
diff --git a/src/mumta/evloop.cpp b/src/mumta/evloop.cpp
new file mode 100644
index 0000000..115aeb4
--- /dev/null
+++ b/src/mumta/evloop.cpp
@@ -0,0 +1,36 @@
+#include "mumta/evloop.hpp"
+
+#include <fcntl.h>
+
+#include <functional>
+#include <memory>
+
+struct stdin_waiter;
+struct stdin_waiter : std::enable_shared_from_this<stdin_waiter>
+{
+    ::ev::io e_stdin;
+
+    stdin_waiter() : e_stdin{} {
+        fcntl(0, F_SETFL, fcntl(0, F_GETFL)|O_NONBLOCK);
+        e_stdin.set<stdin_waiter, &stdin_waiter::cb>(this);
+        e_stdin.set(0, ::ev::READ);
+        e_stdin.start();
+    }
+    ~stdin_waiter() {
+        e_stdin.stop();
+    }
+
+    void cb(::ev::io &w, int events) {
+        (void)w;
+        (void)events;
+        this->e_stdin.stop();
+    }
+};
+
+void rmrf::ev::loop() {
+    ::ev::default_loop defloop;
+
+    auto w = std::make_shared<stdin_waiter>();
+
+    defloop.run(0);
+}
diff --git a/src/mumta/evloop.hpp b/src/mumta/evloop.hpp
new file mode 100644
index 0000000..7aac30e
--- /dev/null
+++ b/src/mumta/evloop.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <ev++.h>
+
+#if !EV_MULTIPLICITY
+#error We require support for multiple event loops
+#endif
+
+namespace rmrf::ev {
+
+bool init_libev();
+bool init_watchdog();
+
+void loop();
+
+}
-- 
GitLab