Run EventManager whenever writing to a file descriptor would block
This approach is not very elegant as it hooks into the event manager deep inside the call graph, but solves the exiting issue and is an okay stop gap solution until a better design comes up. Fixes #4605
This commit is contained in:
parent
3882b0e21b
commit
ae001a1f91
18
src/file.cc
18
src/file.cc
|
@ -5,6 +5,7 @@
|
|||
#include "exception.hh"
|
||||
#include "flags.hh"
|
||||
#include "option_types.hh"
|
||||
#include "event_manager.hh"
|
||||
#include "ranked_match.hh"
|
||||
#include "regex.hh"
|
||||
#include "string.hh"
|
||||
|
@ -256,13 +257,20 @@ void write(int fd, StringView data)
|
|||
const char* ptr = data.data();
|
||||
ssize_t count = (int)data.length();
|
||||
|
||||
int flags = fcntl(fd, F_GETFL, 0);
|
||||
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
auto restore_flags = on_scope_end([&] { fcntl(fd, F_SETFL, flags); });
|
||||
|
||||
while (count)
|
||||
{
|
||||
ssize_t written = ::write(fd, ptr, count);
|
||||
ptr += written;
|
||||
count -= written;
|
||||
|
||||
if (written == -1)
|
||||
if (ssize_t written = ::write(fd, ptr, count); written != -1)
|
||||
{
|
||||
ptr += written;
|
||||
count -= written;
|
||||
}
|
||||
else if (errno == EAGAIN and EventManager::has_instance())
|
||||
EventManager::instance().handle_next_events(EventMode::Urgent, nullptr, false);
|
||||
else
|
||||
throw file_access_error(format("fd: {}", fd), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
|
1
test/regression/4605-fifo-hang/cmd
Normal file
1
test/regression/4605-fifo-hang/cmd
Normal file
|
@ -0,0 +1 @@
|
|||
|
5
test/regression/4605-fifo-hang/rc
Normal file
5
test/regression/4605-fifo-hang/rc
Normal file
|
@ -0,0 +1,5 @@
|
|||
exec 5000oabcdefghi<esc>%yppppp
|
||||
nop %sh{
|
||||
echo "write $kak_response_fifo" > "$kak_command_fifo"
|
||||
strace -o /tmp/strace.log cat "$kak_response_fifo"
|
||||
}
|
Loading…
Reference in New Issue
Block a user