commit:     025fd4424cdb2fc189a5f1dce1e8f9ddae40d7c5
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Sun Dec  7 19:01:19 2025 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Sun Dec  7 19:01:19 2025 +0000
URL:        https://gitweb.gentoo.org/proj/steve.git/commit/?id=025fd442

Ensure correct process cleanup

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

 steve.cxx | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/steve.cxx b/steve.cxx
index 60bb3a5..92615bd 100644
--- a/steve.cxx
+++ b/steve.cxx
@@ -201,16 +201,47 @@ static void steve_handle_pidfd(evutil_socket_t pid_fd, 
short, void *userdata) {
 
        for (auto it = state->processes.begin(); it != state->processes.end(); 
++it) {
                if (it->second.pid_fd == pid_fd) {
+                       uint64_t pid = it->first;
+
+                       /* remove all waiters */
+                       for (auto wit = state->waiters.begin(); wit != 
state->waiters.end();) {
+                               if (wit->pid != pid) {
+                                       ++wit;
+                                       continue;
+                               }
+
+                               if (fuse_req_t *read_req = 
std::get_if<fuse_req_t>(&wit->handle)) {
+                                       /* can we even have read waiters at 
this point? */
+                                       fuse_reply_err(*read_req, EPIPE);
+                                       if (state->verbose)
+                                               std::print(stderr, "Cleaning up 
read waiter for PID {}\n", wit->pid);
+                               } else if (fuse_pollhandle **poll_handle = 
std::get_if<fuse_pollhandle *>(&wit->handle)) {
+                                       /* notify the poller, just in case */
+                                       fuse_lowlevel_notify_poll(*poll_handle);
+                                       if (state->verbose)
+                                               std::print(stderr, "Cleaning up 
poll notification for PID {}\n", wit->pid);
+                               } else
+                                       assert(0 && "invalid waiter");
+
+                               wit = state->waiters.erase(wit);
+                       }
+
+                       /* return all tokens held */
                        state->tokens += it->second.tokens_held;
                        if (it->second.token_reserved)
                                ++state->tokens;
                        if (state->verbose || it->second.tokens_held > 0) {
                                std::print(stderr, "Process {} exited while 
holding {} tokens, token reserved: {}, "
                                                "{} tokens available after 
returning them\n",
-                                               it->first, 
it->second.tokens_held, it->second.token_reserved, state->tokens);
+                                               pid, it->second.tokens_held, 
it->second.token_reserved, state->tokens);
                        }
+
+                       /* remove the process */
                        state->processes.erase(it);
+                       /* if we have new tokens, wake the waiters */
                        steve_wake_waiters(state);
+                       /* make sure the process was removed */
+                       assert(state->processes.find(pid) == 
state->processes.end());
                        return;
                }
        }

Reply via email to