diff --git a/include/empio.h b/include/empio.h index 673a857b..51786505 100644 --- a/include/empio.h +++ b/include/empio.h @@ -44,6 +44,7 @@ extern struct iop *io_open(int, int, int); extern void io_init(void); extern void io_close(struct iop *, struct timeval *); +extern void io_timeout(struct timeval *, time_t); extern int io_input(struct iop *, struct timeval *); extern int io_inputwaiting(struct iop *); extern int io_outputwaiting(struct iop *); diff --git a/src/lib/empthread/io.c b/src/lib/empthread/io.c index f73d89d5..b440a4f3 100644 --- a/src/lib/empthread/io.c +++ b/src/lib/empthread/io.c @@ -124,6 +124,24 @@ io_close(struct iop *iop, struct timeval *timeout) free(iop); } +void +io_timeout(struct timeval *timeout, time_t deadline) +{ + struct timeval now; + + gettimeofday(&now, NULL); + if (now.tv_sec >= deadline) { + /* deadline reached already */ + timeout->tv_sec = 0; + timeout->tv_usec = 0; + } else { + /* deadline in future */ + timeout->tv_sec = deadline - now.tv_sec - 1; + timeout->tv_usec = 999999 - now.tv_usec; + /* yes, this is 1usec early; sue me */ + } +} + /* * Read input from IOP and enqueue it. * If TIMEOUT is non-null, wait at most that long for input to arrive. diff --git a/src/lib/player/accept.c b/src/lib/player/accept.c index 46a6b17c..ad1e78a0 100644 --- a/src/lib/player/accept.c +++ b/src/lib/player/accept.c @@ -100,8 +100,7 @@ player_delete(struct player *lp) if (lp->iop) { /* it's a real player */ - timeout.tv_sec = minutes(max_idle); - timeout.tv_usec = 0; + io_timeout(&timeout, player->curup + minutes(max_idle)); io_close(lp->iop, &timeout); lp->iop = NULL; } diff --git a/src/lib/player/login.c b/src/lib/player/login.c index 324d31b5..61e011d9 100644 --- a/src/lib/player/login.c +++ b/src/lib/player/login.c @@ -90,8 +90,7 @@ player_login(void *ud) for (;;) { io_output(player->iop, 1); if (io_gets(player->iop, buf, sizeof(buf)) < 0) { - timeout.tv_sec = minutes(max_idle); - timeout.tv_usec = 0; + io_timeout(&timeout, player->curup + minutes(max_idle)); res = io_input(player->iop, &timeout); if (res <= 0) { if (res == 0 && !io_eof(player->iop)) diff --git a/src/lib/player/recvclient.c b/src/lib/player/recvclient.c index 33c3cbbe..f9e7d5bc 100644 --- a/src/lib/player/recvclient.c +++ b/src/lib/player/recvclient.c @@ -92,8 +92,7 @@ recvclient(char *cmd, int size) if (player->aborted) break; - timeout.tv_sec = minutes(max_idle); - timeout.tv_usec = 0; + io_timeout(&timeout, player->curup + minutes(max_idle)); res = io_input(player->iop, &timeout); if (res > 0) ;