mirror of
https://github.com/neovim/neovim.git
synced 2026-04-30 11:14:10 +00:00
fix(process): use poll() to drain PTY master on Linux (#38005)
On Linux, libuv's polling (which uses epoll) doesn't flush PTY master's pending work on kernel workqueue, so use an explicit poll() before that.
This commit is contained in:
@@ -3,6 +3,9 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
#ifdef __linux__
|
||||||
|
# include <poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "klib/kvec.h"
|
#include "klib/kvec.h"
|
||||||
#include "nvim/channel.h"
|
#include "nvim/channel.h"
|
||||||
@@ -391,9 +394,17 @@ static void flush_stream(Proc *proc, RStream *stream)
|
|||||||
|
|
||||||
// Read remaining data.
|
// Read remaining data.
|
||||||
while (!stream->s.closed && stream->num_bytes < max_bytes) {
|
while (!stream->s.closed && stream->num_bytes < max_bytes) {
|
||||||
// Remember number of bytes before polling
|
// Remember number of bytes before polling.
|
||||||
size_t num_bytes = stream->num_bytes;
|
size_t num_bytes = stream->num_bytes;
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
// On Linux, libuv's polling (which uses epoll) doesn't flush PTY master's pending
|
||||||
|
// work on kernel workqueue, so use an explcit poll() before that. #37982
|
||||||
|
if (proc->type == kProcTypePty && !stream->did_eof) {
|
||||||
|
struct pollfd pollfd = { .fd = ((PtyProc *)proc)->tty_fd, .events = POLLIN };
|
||||||
|
poll(&pollfd, 1, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// Poll for data and process the generated events.
|
// Poll for data and process the generated events.
|
||||||
loop_poll_events(proc->loop, 0);
|
loop_poll_events(proc->loop, 0);
|
||||||
if (stream->s.events) {
|
if (stream->s.events) {
|
||||||
|
|||||||
Reference in New Issue
Block a user