handle ttyfd out event priorly when write buffer is full

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
This commit is contained in:
Gao feng
2016-07-29 12:57:42 +08:00
parent d3cfa23dde
commit 9a6738d84d
3 changed files with 45 additions and 6 deletions
+23 -1
View File
@@ -96,6 +96,26 @@ int hyper_modify_event(int efd, struct hyper_event *he, int flag)
return 0; 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) static int hyper_getmsg_len(struct hyper_event *he, uint32_t *len)
{ {
struct hyper_buf *buf = &he->rbuf; 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); memmove(buf->data, buf->data + len, buf->get);
if (buf->get == 0) { 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; return 0;
+4
View File
@@ -32,8 +32,12 @@ struct hyper_event {
void *ptr; void *ptr;
}; };
#define FULL(buf) \
(buf->size - buf->get <= 12)
int hyper_add_event(int efd, struct hyper_event *de, int flag); 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_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, int hyper_init_event(struct hyper_event *de, struct hyper_event_ops *ops,
void *arg); void *arg);
int hyper_handle_event(int efd, struct epoll_event *event); int hyper_handle_event(int efd, struct epoll_event *event);
+18 -5
View File
@@ -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) static int pts_loop(struct hyper_event *de, uint64_t seq, int efd, struct hyper_exec *exec)
{ {
int size = -1; int size = -1;
int flag = de->flag | EPOLLOUT;
struct hyper_buf *buf = &ctl.tty.wbuf; 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); size = read(de->fd, buf->data + buf->get + 12, buf->size - buf->get - 12);
fprintf(stdout, "%s: read %d data\n", __func__, size); fprintf(stdout, "%s: read %d data\n", __func__, size);
if (size < 0) { 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 if (size == 0) { // eof
pts_hup(de, efd, exec); pts_hup(de, efd, exec);
break; return 0;
} }
hyper_set_be64(buf->data + buf->get, seq); hyper_set_be64(buf->data + buf->get, seq);
hyper_set_be32(buf->data + buf->get + 8, size + 12); hyper_set_be32(buf->data + buf->get + 8, size + 12);
buf->get += size + 12; buf->get += size + 12;
} } while (!FULL(buf));
if (hyper_modify_event(ctl.efd, &ctl.tty, EPOLLIN | EPOLLOUT) < 0) { if (FULL(buf)) {
fprintf(stderr, "modify ctl tty event to in & out failed\n"); 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; return -1;
} }