From 9a6738d84d78ac62be7a42f007e792c56c83c1f1 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 29 Jul 2016 12:57:42 +0800 Subject: [PATCH] handle ttyfd out event priorly when write buffer is full Signed-off-by: Gao feng --- src/event.c | 24 +++++++++++++++++++++++- src/event.h | 4 ++++ src/exec.c | 23 ++++++++++++++++++----- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/event.c b/src/event.c index 775efb4..bf31dd2 100644 --- a/src/event.c +++ b/src/event.c @@ -96,6 +96,26 @@ int hyper_modify_event(int efd, struct hyper_event *he, int flag) return 0; } +int hyper_requeue_event(int efd, struct hyper_event *ev) +{ + struct epoll_event event = { + .events = ev->flag, + .data.ptr = ev, + }; + + if (epoll_ctl(efd, EPOLL_CTL_DEL, ev->fd, NULL) < 0) { + perror("epoll_ctl del fd failed"); + return -1; + } + + if (epoll_ctl(efd, EPOLL_CTL_ADD, ev->fd, &event) < 0) { + perror("epoll_ctl add fd failed"); + return -1; + } + + return 0; +} + static int hyper_getmsg_len(struct hyper_event *he, uint32_t *len) { struct hyper_buf *buf = &he->rbuf; @@ -210,7 +230,9 @@ int hyper_event_write(struct hyper_event *he, int efd) memmove(buf->data, buf->data + len, buf->get); if (buf->get == 0) { - hyper_modify_event(ctl.efd, he, EPOLLIN); + hyper_modify_event(ctl.efd, he, he->flag & ~(EPOLLOUT| EPOLLPRI)); + } else if (!FULL(buf)) { + hyper_modify_event(ctl.efd, he, he->flag & ~EPOLLPRI); } return 0; diff --git a/src/event.h b/src/event.h index 6979c26..5d46ddf 100644 --- a/src/event.h +++ b/src/event.h @@ -32,8 +32,12 @@ struct hyper_event { void *ptr; }; +#define FULL(buf) \ + (buf->size - buf->get <= 12) + int hyper_add_event(int efd, struct hyper_event *de, int flag); int hyper_modify_event(int efd, struct hyper_event *de, int flag); +int hyper_requeue_event(int efd, struct hyper_event *ev); int hyper_init_event(struct hyper_event *de, struct hyper_event_ops *ops, void *arg); int hyper_handle_event(int efd, struct epoll_event *event); diff --git a/src/exec.c b/src/exec.c index 4df4b76..15db093 100644 --- a/src/exec.c +++ b/src/exec.c @@ -106,9 +106,15 @@ static void stderr_hup(struct hyper_event *de, int efd) static int pts_loop(struct hyper_event *de, uint64_t seq, int efd, struct hyper_exec *exec) { int size = -1; + int flag = de->flag | EPOLLOUT; struct hyper_buf *buf = &ctl.tty.wbuf; - while ((buf->get + 12 < buf->size) && size) { + if (FULL(buf)) { + flag |= EPOLLPRI; + goto out; + } + + do { size = read(de->fd, buf->data + buf->get + 12, buf->size - buf->get - 12); fprintf(stdout, "%s: read %d data\n", __func__, size); if (size < 0) { @@ -124,16 +130,23 @@ static int pts_loop(struct hyper_event *de, uint64_t seq, int efd, struct hyper_ } if (size == 0) { // eof pts_hup(de, efd, exec); - break; + return 0; } hyper_set_be64(buf->data + buf->get, seq); hyper_set_be32(buf->data + buf->get + 8, size + 12); buf->get += size + 12; - } + } while (!FULL(buf)); - if (hyper_modify_event(ctl.efd, &ctl.tty, EPOLLIN | EPOLLOUT) < 0) { - fprintf(stderr, "modify ctl tty event to in & out failed\n"); + if (FULL(buf)) { + flag |= EPOLLPRI; + /* del & add event to move event to tail, this gives + * other event a chance to write data to wbuf of tty. */ + hyper_requeue_event(ctl.efd, de); + } +out: + if (hyper_modify_event(ctl.efd, &ctl.tty, flag) < 0) { + fprintf(stderr, "modify ctl tty event to %d failed\n", flag); return -1; }