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, "