From: Markus Armbruster Date: Sun, 11 Mar 2012 08:04:44 +0000 (+0100) Subject: Add deadline support to io_output(), io_output_if_queue_long() X-Git-Tag: v4.3.30~35 X-Git-Url: http://git.pond.sub.org/?p=empserver;a=commitdiff_plain;h=7a3cbf037a79f837ebaca08a556ea770d8c8464e Add deadline support to io_output(), io_output_if_queue_long() Replace parameter wait by deadline. Non-zero wait argument becomes (time_t)-1 argument, zero wait argument becomes zero deadline argument. No functional change, yet. --- diff --git a/include/empio.h b/include/empio.h index 7d68eadb7..0dbf9af29 100644 --- a/include/empio.h +++ b/include/empio.h @@ -47,8 +47,8 @@ extern void io_close(struct iop *, time_t); extern int io_input(struct iop *, time_t); extern int io_inputwaiting(struct iop *); extern int io_outputwaiting(struct iop *); -extern int io_output(struct iop *, int); -extern int io_output_if_queue_long(struct iop *, int); +extern int io_output(struct iop *, time_t); +extern int io_output_if_queue_long(struct iop *, time_t); extern int io_peek(struct iop *, char *, int); extern int io_read(struct iop *, char *, int); extern int io_write(struct iop *, char *, int); diff --git a/src/lib/empthread/io.c b/src/lib/empthread/io.c index 9b7955b50..af6b97dcf 100644 --- a/src/lib/empthread/io.c +++ b/src/lib/empthread/io.c @@ -112,7 +112,7 @@ io_close(struct iop *iop, time_t deadline) char buf[IO_BUFSIZE]; int ret; - while (io_output(iop, 1) > 0) ; + while (io_output(iop, (time_t)-1) > 0) ; shutdown(iop->fd, SHUT_WR); while (empth_select(iop->fd, EMPTH_FD_READ, io_timeout(&timeout, deadline)) > 0) { @@ -216,19 +216,24 @@ io_outputwaiting(struct iop *iop) /* * Write output queued in IOP. - * If WAIT, writing may put the thread to sleep. + * Wait at most until DEADLINE for input to arrive. (time_t)-1 means + * wait as long as it takes (no timeout). + * Does not yield the processor when DEADLINE is zero. + * A wait for output can be cut short by empth_wakeup(). * Return number of bytes written on success, -1 on error. * In particular, return zero when nothing was written because the - * queue was empty, or because the write slept and got woken up (only - * if WAIT), or because the write refused to sleep (only if !WAIT). + * queue is empty, and on timeout or early wakeup. Use + * io_outputwaiting() to distinguish timeout and early wakeup from + * empty queue. */ int -io_output(struct iop *iop, int wait) +io_output(struct iop *iop, time_t deadline) { + struct timeval timeout; struct iovec iov[16]; int n, res, cc; - if (wait) + if (deadline) ef_make_stale(); if ((iop->flags & IO_WRITE) == 0) @@ -240,8 +245,9 @@ io_output(struct iop *iop, int wait) if (!ioq_qsize(iop->output)) return 0; - if (wait) { - res = empth_select(iop->fd, EMPTH_FD_WRITE, NULL); + if (deadline) { + res = empth_select(iop->fd, EMPTH_FD_WRITE, + io_timeout(&timeout, deadline)); if (res == 0) return 0; if (res < 0) { @@ -267,25 +273,27 @@ io_output(struct iop *iop, int wait) /* * Write output queued in IOP if enough have been enqueued. * Write if at least one buffer has been filled since the last write. - * If WAIT, writing may put the thread to sleep. + * Wait at most until DEADLINE for output to be accepted. (time_t)-1 + * means wait as long as it takes (no timeout). + * Does not yield the processor when DEADLINE is zero. + * A wait for output can be cut short by empth_wakeup(). * Return number of bytes written on success, -1 on error. * In particular, return zero when nothing was written because the - * queue was not long, or the write slept and got woken up (only if - * WAIT), or the write refused to sleep (only if !WAIT). + * queue isn't long, and on timeout or early wakeup. */ int -io_output_if_queue_long(struct iop *iop, int wait) +io_output_if_queue_long(struct iop *iop, time_t deadline) { int len = ioq_qsize(iop->output); if (CANT_HAPPEN(iop->last_out > len)) iop->last_out = 0; if (len - iop->last_out < iop->bufsize) { - if (wait) + if (deadline) ef_make_stale(); return 0; } - return io_output(iop, wait); + return io_output(iop, deadline); } int diff --git a/src/lib/player/login.c b/src/lib/player/login.c index 4fac6e7d4..db517e354 100644 --- a/src/lib/player/login.c +++ b/src/lib/player/login.c @@ -87,7 +87,7 @@ player_login(void *ud) pr_id(player, C_INIT, "Empire server ready\n"); for (;;) { - io_output(player->iop, 1); + io_output(player->iop, (time_t)-1); if (io_gets(player->iop, buf, sizeof(buf)) < 0) { res = io_input(player->iop, player->curup + minutes(max_idle)); if (res <= 0) { diff --git a/src/lib/player/recvclient.c b/src/lib/player/recvclient.c index 2f798cd55..97cc86177 100644 --- a/src/lib/player/recvclient.c +++ b/src/lib/player/recvclient.c @@ -61,6 +61,7 @@ int recvclient(char *cmd, int size) { int count, res; + time_t deadline; count = -1; while (!player->aborted) { @@ -80,8 +81,9 @@ recvclient(char *cmd, int size) * Flush all queued output before potentially sleeping in * io_input(), to make sure player sees the prompt. */ - while (io_output(player->iop, - player->may_sleep >= PLAYER_SLEEP_ON_INPUT) > 0) + deadline = (time_t)(player->may_sleep >= PLAYER_SLEEP_ON_INPUT + ? -1 : 0); + while (io_output(player->iop, deadline) > 0) ; /* diff --git a/src/lib/subs/pr.c b/src/lib/subs/pr.c index 86fd4bb55..e51fbbaeb 100644 --- a/src/lib/subs/pr.c +++ b/src/lib/subs/pr.c @@ -30,7 +30,7 @@ * Dave Pare, 1986, 1989 * Steve McClure, 1998-2000 * Ron Koenderink, 2005 - * Markus Armbruster, 2005-2011 + * Markus Armbruster, 2005-2012 */ /* @@ -223,6 +223,7 @@ pr_player(struct player *pl, int id, char *buf) char *p; char *bp; int len; + time_t deadline; journal_output(pl, id, buf); @@ -247,8 +248,9 @@ pr_player(struct player *pl, int id, char *buf) } if (player == pl) { - while (io_output_if_queue_long(pl->iop, - pl->may_sleep == PLAYER_SLEEP_FREELY) > 0) + deadline = (time_t)(pl->may_sleep == PLAYER_SLEEP_FREELY + ? -1 : 0); + while (io_output_if_queue_long(pl->iop, deadline) > 0) ; } } @@ -266,6 +268,7 @@ upr_player(struct player *pl, int id, char *buf) int standout = 0; char printbuf[2]; char ch; + time_t deadline; journal_output(pl, id, buf); @@ -305,8 +308,9 @@ upr_player(struct player *pl, int id, char *buf) } if (player == pl) { - while (io_output_if_queue_long(pl->iop, - pl->may_sleep == PLAYER_SLEEP_FREELY) > 0) + deadline = (time_t)(pl->may_sleep == PLAYER_SLEEP_FREELY + ? -1 : 0); + while (io_output_if_queue_long(pl->iop, deadline) > 0) ; } }