commit:     e9a72332e2310658c576ac5b761f6b034f381b67
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Sat Nov 22 15:42:27 2025 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Sat Nov 22 15:42:27 2025 +0000
URL:        https://gitweb.gentoo.org/proj/steve.git/commit/?id=e9a72332

Use libevent for event loop

Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>

 meson.build |  3 ++-
 steve.cxx   | 58 ++++++++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/meson.build b/meson.build
index 6d86068..693c753 100644
--- a/meson.build
+++ b/meson.build
@@ -1,7 +1,8 @@
 project('steve', 'cpp')
 
 fuse3 = dependency('fuse3')
+libevent = dependency('libevent', version: '>= 2')
 
 executable('steve', ['steve.cxx'],
-           dependencies: [fuse3],
+           dependencies: [fuse3, libevent],
            install : true)

diff --git a/steve.cxx b/steve.cxx
index 50067d6..2ab4e15 100644
--- a/steve.cxx
+++ b/steve.cxx
@@ -24,6 +24,8 @@
 #include <sys/poll.h>
 #include <unistd.h>
 
+#include <event2/event.h>
+
 #include <cuse_lowlevel.h>
 #include <fuse.h>
 #include <fuse_opt.h>
@@ -310,22 +312,36 @@ static const struct cuse_lowlevel_ops steve_ops = {
        .poll = steve_poll,
 };
 
-static steve_state *steve_global_state;
-
-static void steve_handle_sigusr1(int, siginfo_t *, void *) {
-       steve_check_processes(steve_global_state);
+static void steve_handle_sigusr1(evutil_socket_t, short, void *userdata) {
+       steve_state *state = static_cast<steve_state *>(userdata);
+       steve_check_processes(state);
 
        printf("steve: currently %d tokens available out of %d\n",
-                       steve_global_state->tokens, steve_global_state->jobs);
-       for (auto it : steve_global_state->processes) {
+                       state->tokens, state->jobs);
+       for (auto it : state->processes) {
                printf("PID %ld holds %d tokens\n", it.first, 
it.second.tokens_held);
        }
 }
 
+static void steve_handle_cuse(evutil_socket_t, short, void *userdata) {
+       struct fuse_session *session = static_cast<struct fuse_session 
*>(userdata);
+       struct fuse_buf buf = {0};
+
+       if (fuse_session_receive_buf(session, &buf) > 0)
+               fuse_session_process_buf(session, &buf);
+}
+
 int main(int argc, char **argv)
 {
        steve_state state = { 0 };
 
+       std::unique_ptr<struct event_base, std::function<void(struct 
event_base*)>>
+               evb{event_base_new(), event_base_free};
+       if (!evb) {
+               fprintf(stderr, "failed to initialize libevent\n");
+               return 1;
+       }
+
        struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
        if (fuse_opt_parse(&args, &state, steve_opts, steve_process_arg)) {
                fprintf(stderr, "failed to parse option\n");
@@ -357,6 +373,26 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       std::unique_ptr<struct event, std::function<void(struct event*)>>
+               cuse_event{event_new(evb.get(), cuse_fd, EV_READ|EV_PERSIST, 
steve_handle_cuse, session.get()), event_free};
+       if (!cuse_event) {
+               fprintf(stderr, "failed to initialize CUSE handler");
+               close(cuse_fd);
+               fuse_opt_free_args(&args);
+               return 1;
+       }
+       event_add(cuse_event.get(), nullptr);
+
+       std::unique_ptr<struct event, std::function<void(struct event*)>>
+               sigusr1_event{evsignal_new(evb.get(), SIGUSR1, 
steve_handle_sigusr1, &state), event_free};
+       if (!sigusr1_event) {
+               fprintf(stderr, "failed to initialize signal handler");
+               close(cuse_fd);
+               fuse_opt_free_args(&args);
+               return 1;
+       }
+       event_add(sigusr1_event.get(), nullptr);
+
        std::string mountpoint = "/dev/fd/" + std::to_string(cuse_fd);
        if (fuse_session_mount(session.get(), mountpoint.c_str()) == -1) {
                fprintf(stderr, "failed to mount the filesystem");
@@ -365,15 +401,9 @@ int main(int argc, char **argv)
                return 1;
        }
 
-       steve_global_state = &state;
-       struct sigaction sigact = { 0 };
-       sigact.sa_flags = SA_SIGINFO;
-       sigact.sa_sigaction = steve_handle_sigusr1;
-       sigaction(SIGUSR1, &sigact, NULL);
-
-       int ret = fuse_session_loop(session.get());
+       event_base_dispatch(evb.get());
        fuse_session_unmount(session.get());
        close(cuse_fd);
        fuse_opt_free_args(&args);
-       return !!ret;
+       return 0;
 }

Reply via email to