1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-05-09 13:42:09 -05:00

Proper backlog handling in Unix pty backend.

If the Seat that the pty backend is talking to starts to back up, then
we ought to temporarily stop reading from the pty device, to pass that
back-pressure on to whatever's running in the terminal.

Previously, this didn't matter because a Seat running a GUI terminal
never backed up anyway. But now it does, so we should support it all
the way through the system.
This commit is contained in:
Simon Tatham 2021-12-19 11:15:50 +00:00
parent 4721571b8b
commit f780a45c57

View File

@ -73,6 +73,7 @@ struct Pty {
int master_i, master_o, master_e;
Seat *seat;
size_t output_backlog;
char name[FILENAME_MAX];
pid_t child_pid;
int term_width, term_height;
@ -83,6 +84,8 @@ struct Pty {
Backend backend;
};
#define PTY_MAX_BACKLOG 32768
/*
* We store all the (active) PtyFd structures in a tree sorted by fd,
* so that when we get an uxsel notification we know which backend
@ -589,6 +592,7 @@ void pty_pre_init(void)
}
static void pty_try_wait(void);
static void pty_uxsel_setup(Pty *pty);
static void pty_real_select_result(Pty *pty, int fd, int event, int status)
{
@ -673,7 +677,9 @@ static void pty_real_select_result(Pty *pty, int fd, int event, int status)
perror("read pty master");
exit(1);
} else if (ret > 0) {
seat_output(pty->seat, !is_stdout, buf, ret);
pty->output_backlog = seat_output(
pty->seat, !is_stdout, buf, ret);
pty_uxsel_setup(pty);
}
} else if (event == SELECT_W) {
/*
@ -775,8 +781,10 @@ static void pty_uxsel_setup_fd(Pty *pty, int fd)
if (fd < 0)
return;
/* read from standard output and standard error pipes */
if (pty->master_o == fd || pty->master_e == fd)
/* read from standard output and standard error pipes, assuming
* we're not too backlogged */
if ((pty->master_o == fd || pty->master_e == fd) &&
pty->output_backlog < PTY_MAX_BACKLOG)
rwx |= SELECT_R;
/* write to standard input pipe if we have any data */
if (pty->master_i == fd && bufchain_size(&pty->output_data))
@ -1514,8 +1522,9 @@ static bool pty_sendok(Backend *be)
static void pty_unthrottle(Backend *be, size_t backlog)
{
/* Pty *pty = container_of(be, Pty, backend); */
/* do nothing */
Pty *pty = container_of(be, Pty, backend);
pty->output_backlog = backlog;
pty_uxsel_setup(pty);
}
static bool pty_ldisc(Backend *be, int option)