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;
}