pty: read all available data instead of only one chunk

If there is plenty data available, we should read all of it before
returning. Otherwise, we might spend too much time letting the other
subsystems perform actions. This can have the effect, that we render after
each read() on the pty if a redraw takes more time than a single frame.
This is definitely not what we want.

To avoid staying here too long we use a hard-coded maximum. Otherwise, if
the vte layer takes longer than the pty-end writes data to us, we might
stay here forever. This is very unlikely as the VTE layer as no immediate
side-effects that make long computations, but we use it to be on the safe
side.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-08-21 17:44:43 +02:00
parent 5f59c7953c
commit a05815eb71

View File

@ -292,7 +292,7 @@ static int send_buf(struct kmscon_pty *pty)
static void pty_input(struct ev_fd *fd, int mask, void *data)
{
int ret;
ssize_t len;
ssize_t len, num;
struct kmscon_pty *pty = data;
if (mask & EV_ERR) {
@ -310,17 +310,21 @@ static void pty_input(struct ev_fd *fd, int mask, void *data)
}
if (mask & EV_READABLE) {
len = read(pty->fd, pty->io_buf, sizeof(pty->io_buf));
if (len > 0) {
if (pty->input_cb)
pty->input_cb(pty, pty->io_buf, len, pty->data);
} else if (len == 0) {
log_debug("child closed remote end");
goto err;
} else if (errno != EWOULDBLOCK) {
log_err("cannot read from pty: %m");
goto err;
}
/* use a maximum of 50 steps to avoid staying here forever */
num = 50;
do {
len = read(pty->fd, pty->io_buf, sizeof(pty->io_buf));
if (len > 0) {
if (pty->input_cb)
pty->input_cb(pty, pty->io_buf, len, pty->data);
} else if (len == 0) {
log_debug("child closed remote end");
goto err;
} else if (errno != EWOULDBLOCK) {
log_err("cannot read from pty: %m");
goto err;
}
} while (len > 0 && --num);
}
return;