commit: f1d2a62cf085871c53d89cb75e0e74c016e74c16
Author: Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 18 09:14:20 2025 +0000
Commit: Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Tue Nov 18 09:14:20 2025 +0000
URL: https://gitweb.gentoo.org/proj/steve.git/commit/?id=f1d2a62c
Initial support for token reclaiming
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
steve.cxx | 51 ++++++++++++++++++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 15 deletions(-)
diff --git a/steve.cxx b/steve.cxx
index 0ff6bb0..81e88f4 100644
--- a/steve.cxx
+++ b/steve.cxx
@@ -13,6 +13,7 @@
#include <cstdio>
#include <cstdlib>
#include <cerrno>
+#include <csignal>
#include <deque>
#include <unordered_map>
@@ -89,6 +90,37 @@ static int steve_process_arg(
return 0;
}
+static void steve_wake_waiters(steve_state *state)
+{
+ while (state->tokens > 0 && !state->read_waiters.empty()) {
+ const steve_read_waiter *read_waiter =
&state->read_waiters.front();
+
+ state->tokens--;
+ state->processes[read_waiter->pid].tokens_held++;
+ if (state->verbose)
+ printf("Giving job token to PID %ld, %d left, %d tokens
held by process\n",
+ read_waiter->pid, state->tokens,
state->processes[read_waiter->pid].tokens_held);
+ fuse_reply_buf(read_waiter->req, "+", 1);
+ state->read_waiters.pop_front();
+ }
+}
+
+static void steve_check_processes(steve_state *state)
+{
+ for (auto it = state->processes.begin(); it != state->processes.end();)
+ {
+ if (kill(it->first, 0) == -1 && errno == ESRCH) {
+ state->tokens += it->second.tokens_held;
+ fprintf(stderr, "Process %ld disappeared while holding
%d tokens, "
+ "%d tokens available after returning
them\n",
+ it->first, it->second.tokens_held,
state->tokens);
+ it = state->processes.erase(it);
+ steve_wake_waiters(state);
+ } else
+ ++it;
+ }
+}
+
static void steve_init(void *userdata, struct fuse_conn_info *conn)
{
steve_state *state = static_cast<steve_state *>(userdata);
@@ -157,6 +189,10 @@ static void steve_read(
return;
}
+ /* check if we have tokens to reclaim */
+ if (state->tokens == 0)
+ steve_check_processes(state);
+
/* no need to support reading more than one token at a time */
if (state->tokens > 0) {
state->tokens--;
@@ -180,21 +216,6 @@ static void steve_read(
fuse_req_interrupt_func(req, steve_interrupt, state);
}
-static void steve_wake_waiters(steve_state *state)
-{
- while (state->tokens > 0 && !state->read_waiters.empty()) {
- const steve_read_waiter *read_waiter =
&state->read_waiters.front();
-
- state->tokens--;
- state->processes[read_waiter->pid].tokens_held++;
- if (state->verbose)
- printf("Giving job token to PID %ld, %d left, %d tokens
held by process\n",
- read_waiter->pid, state->tokens,
state->processes[read_waiter->pid].tokens_held);
- fuse_reply_buf(read_waiter->req, "+", 1);
- state->read_waiters.pop_front();
- }
-}
-
static void steve_write(
fuse_req_t req, const char *buf, size_t size, off_t off,
struct fuse_file_info *fi)