Add deadline support to io_output(), io_output_if_queue_long()
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 11 Mar 2012 08:04:44 +0000 (09:04 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Thu, 26 Apr 2012 17:43:22 +0000 (19:43 +0200)
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.

include/empio.h
src/lib/empthread/io.c
src/lib/player/login.c
src/lib/player/recvclient.c
src/lib/subs/pr.c

index 7d68eadb73d75866410eae0e2b16d14b057d1ec0..0dbf9af29b557f8b574bb711552a22413a2b4260 100644 (file)
@@ -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);
index 9b7955b50b72235009e37f37f69db5e36e6d184b..af6b97dcf6a2a541c7bf99c54f2149ca79784c94 100644 (file)
@@ -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
index 4fac6e7d4a5bd188887154a57cd09a8a8d9d5b4e..db517e354b1ada56ebffc3f69027ea6c0717a407 100644 (file)
@@ -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) {
index 2f798cd558bc8ba7422dcf8348d8af0400a135fc..97cc861771329e5bb51e656eff414b85ea0f2d35 100644 (file)
@@ -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)
            ;
 
        /*
index 86fd4bb55026c37bd63650e3375d254bf880f8fd..e51fbbaebdfc961d7377dcabd02f354bce1d3bdc 100644 (file)
@@ -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)
            ;
     }
 }