commit:     2476f727d2ef158a76b59a9c80f4c3f5440d4f97
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Sun Dec  7 18:11:02 2025 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Sun Dec  7 18:11:02 2025 +0000
URL:        https://gitweb.gentoo.org/proj/steve.git/commit/?id=2476f727

Use a single steve_waiter type

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

 steve.cxx | 51 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 32 insertions(+), 19 deletions(-)

diff --git a/steve.cxx b/steve.cxx
index ce3b9f8..9280d88 100644
--- a/steve.cxx
+++ b/steve.cxx
@@ -23,6 +23,7 @@
 #include <print>
 #include <string>
 #include <unordered_map>
+#include <variant>
 
 #include <getopt.h>
 #include <sys/poll.h>
@@ -38,23 +39,35 @@
 #include "steve.h"
 #include "util.hxx"
 
-struct steve_read_waiter {
-       fuse_req_t req;
+struct steve_waiter {
+       std::variant<fuse_req_t, fuse_pollhandle *> handle;
        uint64_t pid;
-};
 
-struct steve_poll_waiter {
-       fuse_pollhandle *poll_handle;
-       uint64_t pid;
+       steve_waiter(fuse_req_t new_req, uint64_t new_pid)
+               : handle(new_req), pid(new_pid) {}
+       steve_waiter(fuse_pollhandle *new_poll_handle, uint64_t new_pid)
+               : handle(new_poll_handle), pid(new_pid) {}
 
-       steve_poll_waiter(fuse_pollhandle *new_poll_handle, uint64_t new_pid)
-               : poll_handle(new_poll_handle), pid(new_pid) {}
+       steve_waiter(const steve_waiter &) = delete;
+       steve_waiter& operator=(const steve_waiter &) = delete;
 
-       steve_poll_waiter(const steve_poll_waiter &) = delete;
-       steve_poll_waiter& operator=(const steve_poll_waiter &) = delete;
+       steve_waiter(steve_waiter &&other)
+               : handle(other.handle), pid(other.pid)
+       {
+               other.handle = static_cast<fuse_pollhandle *>(nullptr);
+       }
+       steve_waiter& operator=(steve_waiter &&other) {
+               handle = other.handle;
+               pid = other.pid;
+               other.handle = static_cast<fuse_pollhandle *>(nullptr);
+               return *this;
+       }
 
-       ~steve_poll_waiter() {
-               fuse_pollhandle_destroy(poll_handle);
+       ~steve_waiter() {
+               if (fuse_pollhandle **poll_handle = std::get_if<fuse_pollhandle 
*>(&handle)) {
+                       if (*poll_handle)
+                               fuse_pollhandle_destroy(*poll_handle);
+               }
        }
 };
 
@@ -76,8 +89,8 @@ struct steve_state {
        double max_load_avg{-1};  /* < 0 implies no load average */
        double load_avg;
        int64_t tokens;
-       std::deque<steve_read_waiter> read_waiters;
-       std::deque<steve_poll_waiter> poll_waiters;
+       std::deque<steve_waiter> read_waiters;
+       std::deque<steve_waiter> poll_waiters;
        std::unordered_map<uint64_t, steve_process> processes;
        struct event_base *evb;
 
@@ -131,8 +144,8 @@ static void steve_give_token(steve_state *state, fuse_req_t 
req, uint64_t pid)
 static void steve_wake_waiters(steve_state *state)
 {
        while (!state->read_waiters.empty() && steve_can_give_token(state) == 
steve_token_availability::available) {
-               const steve_read_waiter *read_waiter = 
&state->read_waiters.front();
-               steve_give_token(state, read_waiter->req, read_waiter->pid);
+               const steve_waiter *read_waiter = &state->read_waiters.front();
+               steve_give_token(state, 
std::get<fuse_req_t>(read_waiter->handle), read_waiter->pid);
                state->read_waiters.pop_front();
        }
 
@@ -141,7 +154,7 @@ static void steve_wake_waiters(steve_state *state)
                        if (state->verbose)
                                std::print(stderr, "Notifying PID {} about 
POLLIN, {} tokens left, {} tokens held by process\n",
                                                poll_waiter.pid, state->tokens, 
state->processes[poll_waiter.pid].tokens_held);
-                       fuse_lowlevel_notify_poll(poll_waiter.poll_handle);
+                       fuse_lowlevel_notify_poll(std::get<fuse_pollhandle 
*>(poll_waiter.handle));
                }
                state->poll_waiters.clear();
        }
@@ -272,7 +285,7 @@ static void steve_interrupt(fuse_req_t req, void *userdata)
 
        fuse_reply_err(req, EINTR);
        for (auto it = state->read_waiters.begin(); it != 
state->read_waiters.end(); ++it) {
-               if (it->req == req) {
+               if (std::get<fuse_req_t>(it->handle) == req) {
                        if (state->verbose)
                                std::print(stderr, "Passed EINTR to PID {}\n", 
it->pid);
                        state->read_waiters.erase(it);
@@ -307,7 +320,7 @@ static void steve_read(
                return;
        }
 
-       state->read_waiters.emplace_back(steve_read_waiter{req, fi->fh});
+       state->read_waiters.emplace_back(steve_waiter{req, fi->fh});
        if (state->verbose) {
                if (token_avail == steve_token_availability::load_exceeded) {
                        std::print(stderr, "Load exceeded while PID {} 
requested token, waiting, {} tokens free, "

Reply via email to