Replace the per-iop input_timeout by per-function timeouts
authorMarkus Armbruster <armbru@pond.sub.org>
Sat, 10 Mar 2012 12:27:34 +0000 (13:27 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Tue, 27 Mar 2012 15:23:14 +0000 (17:23 +0200)
Commit 08b94556 (v4.3.20) added io_open() parameter input_timeout.  It
applies to io_input() and, since commit 904822e3, to io_close().  Add
timeout parameters to these functions instead.

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

index cd51458e8d6e23f301aa5a79f06f1d793ecaf3ad..673a857bbe54db62089032cda87d12b4c30fc08d 100644 (file)
@@ -27,7 +27,7 @@
  *  empio.h: Describes io pointers used in Empire
  *
  *  Known contributors to this file:
- *     Markus Armbruster, 2004-2010
+ *     Markus Armbruster, 2004-2012
  */
 
 #ifndef EMPIO_H
 
 #define IO_BUFSIZE     4096
 
-extern struct iop *io_open(int, int, int, struct timeval);
+extern struct iop *io_open(int, int, int);
 extern void io_init(void);
-extern void io_close(struct iop *);
-extern int io_input(struct iop *, int);
+extern void io_close(struct iop *, struct timeval *);
+extern int io_input(struct iop *, struct timeval *);
 extern int io_inputwaiting(struct iop *);
 extern int io_outputwaiting(struct iop *);
 extern int io_output(struct iop *, int);
index 0e65c86ed972da2c0d49d72fcbd58bcc54818eb4..f73d89d5dd28db6c8d18e55c1852349321e9829c 100644 (file)
@@ -63,7 +63,6 @@ struct iop {
     int flags;
     int bufsize;
     int last_out;
-    struct timeval input_timeout;
 };
 
 void
@@ -72,7 +71,7 @@ io_init(void)
 }
 
 struct iop *
-io_open(int fd, int flags, int bufsize, struct timeval timeout)
+io_open(int fd, int flags, int bufsize)
 {
     int fdfl;
     struct iop *iop;
@@ -97,7 +96,6 @@ io_open(int fd, int flags, int bufsize, struct timeval timeout)
     iop->flags = flags;
     iop->last_out = 0;
     iop->bufsize = bufsize;
-    iop->input_timeout = timeout;
     if (flags & IO_READ)
        iop->input = ioq_create(bufsize);
     if (flags & IO_WRITE)
@@ -106,14 +104,14 @@ io_open(int fd, int flags, int bufsize, struct timeval timeout)
 }
 
 void
-io_close(struct iop *iop)
+io_close(struct iop *iop, struct timeval *timeout)
 {
     char buf[IO_BUFSIZE];
     int ret;
 
     while (io_output(iop, 1) > 0) ;
     shutdown(iop->fd, SHUT_WR);
-    while (empth_select(iop->fd, EMPTH_FD_READ, &iop->input_timeout) > 0) {
+    while (empth_select(iop->fd, EMPTH_FD_READ, timeout) > 0) {
        ret = read(iop->fd, buf, sizeof(buf));
        if (ret <= 0)
            break;
@@ -127,13 +125,16 @@ io_close(struct iop *iop)
 }
 
 /*
- * Return number of bytes read on success, zero on timeout, early
- * wakeup or EOF, -1 on error.  In particular, return 0 when no data
- * is available for non-blocking input (WAITFORINPUT false).
- * Use io_eof() to distinguish timeout and early wakeup from EOF.
+ * Read input from IOP and enqueue it.
+ * If TIMEOUT is non-null, wait at most that long for input to arrive.
+ * Does not yield the processor when timeout is zero.
+ * A wait for input can be cut short by empth_wakeup().
+ * Return number of bytes read on success, -1 on error.
+ * In particular, return zero on timeout, early wakeup or EOF.  Use
+ * io_eof() to distinguish timeout and early wakeup from EOF.
  */
 int
-io_input(struct iop *iop, int waitforinput)
+io_input(struct iop *iop, struct timeval *timeout)
 {
     char buf[IO_BUFSIZE];
     int cc;
@@ -146,9 +147,8 @@ io_input(struct iop *iop, int waitforinput)
     if (iop->flags & IO_EOF)
        return 0;
 
-    /* Wait for the file to have input. */
-    if (waitforinput) {
-       res = empth_select(iop->fd, EMPTH_FD_READ, &iop->input_timeout);
+    if (!timeout || timeout->tv_sec || timeout->tv_usec) {
+       res = empth_select(iop->fd, EMPTH_FD_READ, timeout);
        if (res < 0) {
            iop->flags |= IO_ERROR;
            return -1;
@@ -156,7 +156,6 @@ io_input(struct iop *iop, int waitforinput)
            return 0;
     }
 
-    /* Do the actual read. */
     cc = read(iop->fd, buf, sizeof(buf));
     if (cc < 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK)
@@ -164,14 +163,11 @@ io_input(struct iop *iop, int waitforinput)
        iop->flags |= IO_ERROR;
        return -1;
     }
-
-    /* We eof'd */
     if (cc == 0) {
        iop->flags |= IO_EOF;
        return 0;
     }
 
-    /* Append the input to the IOQ. */
     ioq_append(iop->input, buf, cc);
     return cc;
 }
index 87eb9124d44a27b9e76632ffee1a4222f77ab56b..46a6b17c6d1d50a3ae0d63b066169e1151e15e10 100644 (file)
@@ -28,7 +28,7 @@
  *
  *  Known contributors to this file:
  *     Dave Pare, 1994
- *     Markus Armbruster, 2005-2010
+ *     Markus Armbruster, 2005-2012
  */
 
 #include <config.h>
@@ -71,17 +71,14 @@ struct player *
 player_new(int s)
 {
     struct player *lp;
-    struct timeval idle_timeout;
 
     lp = malloc(sizeof(struct player));
     if (!lp)
        return NULL;
     memset(lp, 0, sizeof(struct player));
-    idle_timeout.tv_sec = max_idle * 60;
-    idle_timeout.tv_usec = 0;
     if (s >= 0) {
        /* real player, not dummy created by update and market update */
-       lp->iop = io_open(s, IO_READ | IO_WRITE, IO_BUFSIZE, idle_timeout);
+       lp->iop = io_open(s, IO_READ | IO_WRITE, IO_BUFSIZE);
        if (!lp->iop) {
            free(lp);
            return NULL;
@@ -98,11 +95,14 @@ player_new(int s)
 struct player *
 player_delete(struct player *lp)
 {
+    struct timeval timeout;
     struct player *back;
 
     if (lp->iop) {
        /* it's a real player */
-       io_close(lp->iop);
+       timeout.tv_sec = minutes(max_idle);
+       timeout.tv_usec = 0;
+       io_close(lp->iop, &timeout);
        lp->iop = NULL;
     }
     back = (struct player *)lp->queue.q_back;
index fd56f531dfa6e34c5a2f11a622779545b108772b..324d31b5f856757e79bc5aac908abecce35c5126 100644 (file)
@@ -76,6 +76,7 @@ static struct cmndstr login_coms[] = {
 void
 player_login(void *ud)
 {
+    struct timeval timeout;
     char buf[128];
     char space[128];
     int ac;
@@ -89,7 +90,9 @@ player_login(void *ud)
     for (;;) {
        io_output(player->iop, 1);
        if (io_gets(player->iop, buf, sizeof(buf)) < 0) {
-           res = io_input(player->iop, 1);
+           timeout.tv_sec = minutes(max_idle);
+           timeout.tv_usec = 0;
+           res = io_input(player->iop, &timeout);
            if (res <= 0) {
                if (res == 0 && !io_eof(player->iop))
                    pr_id(player, C_DATA, "idle connection terminated\n");
index ed26acfa35fe0bf698dcf12c192c7b28d3dcde58..33c3cbbe53ef9bef39ae424215f77f15db74f739 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "empio.h"
 #include "journal.h"
+#include "optlist.h"
 #include "player.h"
 #include "prototypes.h"
 
@@ -60,6 +61,7 @@ int
 recvclient(char *cmd, int size)
 {
     int count, res;
+    struct timeval timeout;
 
     count = -1;
     while (!player->aborted) {
@@ -90,7 +92,9 @@ recvclient(char *cmd, int size)
        if (player->aborted)
            break;
 
-       res = io_input(player->iop, 1);
+       timeout.tv_sec = minutes(max_idle);
+       timeout.tv_usec = 0;
+       res = io_input(player->iop, &timeout);
        if (res > 0)
            ;
        else if (res < 0)