diff options
| author | Johannes Altmanninger <aclopte@gmail.com> | 2023-11-04 17:23:09 +0100 |
|---|---|---|
| committer | Johannes Altmanninger <aclopte@gmail.com> | 2023-11-04 17:48:25 +0100 |
| commit | b0ddbfc2dfc7de25d3cbda1d39be7da564a1ddac (patch) | |
| tree | 3c8874c9417ed1da2e2fe25e27a329c66d03ff23 /src/remote.cc | |
| parent | 6a39ac224bf0407b0ec5d39ffee72d6308b73cfc (diff) | |
Do not poll command sockets while shell command is running
Accepter is a wrapper around a socket watcher. It always uses
EventMode::Urgent, so it will be included in pselect(2) (via
EventManager::handle_next_events()) even while we are waiting for a
(blocking) shell command. However we will not execute the command
received on this socket until after the shell command is done.
This is implemented with an early return:
void handle_available_input(EventMode mode)
{
while (not m_reader.ready() and fd_readable(sock))
m_reader.read_available(sock);
if (mode != EventMode::Normal or not m_reader.ready())
return;
so we read available data but don't close the socket.
When using this reproducer
{
sleep 1 && echo 'nop' | kak -p session
} &
kak -n -s session -e '%sh{sleep 7}'
the first "m_reader.read_available(sock);" will read "nop". Then
"m_reader.ready()" is true but the socket is still readable. This
means that pselect(2) will return it every time, without blocking.
This means that the shell manager runs a hot loop between pselect(2)
and waitpid(2).
Fix this problem demoting command socket watchers from
EventMode::Urgent. This means that we won't pselect(2) it when handling
only urgent events. Control-C still works, I'm not sure why.
Alternative fix: we could read the commands but then disable the
socket. I tried this but it seems too complex.
Closes #5014
Diffstat (limited to 'src/remote.cc')
| -rw-r--r-- | src/remote.cc | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/remote.cc b/src/remote.cc index 5b97f985..025a4458 100644 --- a/src/remote.cc +++ b/src/remote.cc @@ -776,7 +776,7 @@ class Server::Accepter { public: Accepter(int socket) - : m_socket_watcher(socket, FdEvents::Read, EventMode::Urgent, + : m_socket_watcher(socket, FdEvents::Read, EventMode::Normal, [this](FDWatcher&, FdEvents, EventMode mode) { handle_available_input(mode); }) |
