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:
parent
4721571b8b
commit
f780a45c57
19
unix/pty.c
19
unix/pty.c
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user