commit:     57d72395a337599a2d8013b0c6c7f8f42cae5150
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 18 07:16:21 2025 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Thu Dec 18 07:16:21 2025 +0000
URL:        https://gitweb.gentoo.org/proj/steve.git/commit/?id=57d72395

Return the extra written token unchanged to client

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

 steve.cxx | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/steve.cxx b/steve.cxx
index 596780e..949fe5e 100644
--- a/steve.cxx
+++ b/steve.cxx
@@ -22,6 +22,7 @@
 #include <deque>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <print>
 #include <string>
 #include <unordered_map>
@@ -82,6 +83,7 @@ struct steve_process {
        ssize_t tokens_held{0};
        bool token_reserved{false};
        event_ptr pidfd_event;
+       std::optional<char> extra_token;
 
        ~steve_process() {
                if (pid_fd != -1)
@@ -207,15 +209,28 @@ static steve_token_availability 
steve_can_give_token(steve_state *state, uint64_
        return steve_token_availability::available;
 }
 
+static char steve_get_token_char(steve_state *state, uint64_t pid)
+{
+       if (state->processes[pid].extra_token.has_value()) {
+               char ret = state->processes[pid].extra_token.value();
+               state->processes[pid].extra_token.reset();
+               return ret;
+       }
+
+       return '+';
+}
+
 static void steve_give_token(steve_state *state, fuse_req_t req, uint64_t pid)
 {
+       char token = steve_get_token_char(state, pid);
+
        if (state->processes[pid].token_reserved) {
                state->processes[pid].tokens_held++;
                state->processes[pid].token_reserved = false;
                if (state->verbose)
-                       std::print(stderr, "Giving reserved token to PID {}, {} 
left, {} tokens held by process\n",
-                                       pid, state->tokens, 
state->processes[pid].tokens_held);
-               fuse_reply_buf(req, "+", 1);
+                       std::print(stderr, "Giving reserved token 0x{:2x} to 
PID {}, {} left, {} tokens held by process\n",
+                                       token, pid, state->tokens, 
state->processes[pid].tokens_held);
+               fuse_reply_buf(req, &token, 1);
                return;
        }
 
@@ -223,13 +238,13 @@ static void steve_give_token(steve_state *state, 
fuse_req_t req, uint64_t pid)
        state->processes[pid].tokens_held++;
        if (state->verbose) {
                if (state->max_load_avg > 0)
-                       std::print(stderr, "Giving job token to PID {}, {} 
left, {} tokens held by process, token reserved: {}, load average = {:.3} 
(limit: {})\n",
-                                       pid, state->tokens, 
state->processes[pid].tokens_held, state->processes[pid].token_reserved, 
state->load_avg, state->max_load_avg);
+                       std::print(stderr, "Giving job token 0x{:2x} to PID {}, 
{} left, {} tokens held by process, token reserved: {}, load average = {:.3} 
(limit: {})\n",
+                                       token, pid, state->tokens, 
state->processes[pid].tokens_held, state->processes[pid].token_reserved, 
state->load_avg, state->max_load_avg);
                else
-                       std::print(stderr, "Giving job token to PID {}, {} 
left, {} tokens held by process, token reserved: {}\n",
-                                       pid, state->tokens, 
state->processes[pid].tokens_held, state->processes[pid].token_reserved);
+                       std::print(stderr, "Giving job token 0x{:2x} to PID {}, 
{} left, {} tokens held by process, token reserved: {}\n",
+                                       token, pid, state->tokens, 
state->processes[pid].tokens_held, state->processes[pid].token_reserved);
        }
-       fuse_reply_buf(req, "+", 1);
+       fuse_reply_buf(req, &token, 1);
 }
 
 static void steve_reserve_token(steve_state *state, uint64_t pid)
@@ -496,7 +511,7 @@ static void steve_read(
 }
 
 static void steve_write(
-       fuse_req_t req, const char *, size_t size, off_t off,
+       fuse_req_t req, const char *data, size_t size, off_t off,
        struct fuse_file_info *fi)
 {
        steve_state *state = static_cast<steve_state *>(fuse_req_userdata(req));
@@ -514,8 +529,10 @@ static void steve_write(
 
        /* workaround for https://github.com/medek/nasm-rs/issues/44 */
        if (state->processes[fi->fh].tokens_held == 0 && size == 1) {
-               std::print(stderr, "Warning: process {} pre-released an 
unacquired token, please report a bug upstream\n",
-                               fi->fh);
+               assert(!state->processes[fi->fh].extra_token.has_value());
+               state->processes[fi->fh].extra_token = data[0];
+               std::print(stderr, "Warning: process {} pre-released an 
unacquired token 0x{:2x}, please report a bug upstream\n",
+                               fi->fh, data[0]);
        } else if (state->processes[fi->fh].tokens_held < 
static_cast<ssize_t>(size)) {
                std::print(stderr, "Warning: process {} tried to return {} 
tokens while holding only {} tokens, capping\n",
                                fi->fh, size, 
state->processes[fi->fh].tokens_held);

Reply via email to