Reimplement max_idle without a separate thread

Remove the KillIdle thread.  Add timeout to struct iop, initialized in
io_open().  Obey it in io_input() by passing it to empth_select().  If
empth_select() times out, report that back through io_input() to
recvclient() and player_login().  If player_login() receives a timeout
indication, print a message and terminate the session.  If
recvclient() receives a timeout indication, flash a message to the
player and initiate a shut down the player's session.

Create WIN32 sys/time.h to define struct timeval.  This creates some
conflicts with WIN32 windows.h definitions.  Including windows.h in
show.c and info.c creates conflicts, so remove that.  Modify service.c
to include sys/socket.h instead of windows.h to remove the conflict
with sys/time.h.
This commit is contained in:
Ron Koenderink 2009-02-01 06:22:26 -06:00 committed by Markus Armbruster
parent a7ee69d112
commit 08b9455682
17 changed files with 181 additions and 133 deletions

View file

@ -61,6 +61,7 @@ struct iop {
struct ioqueue *output;
int flags;
int bufsize;
struct timeval input_timeout;
};
void
@ -69,7 +70,7 @@ io_init(void)
}
struct iop *
io_open(int fd, int flags, int bufsize)
io_open(int fd, int flags, int bufsize, struct timeval timeout)
{
struct iop *iop;
@ -83,6 +84,7 @@ io_open(int fd, int flags, int bufsize)
iop->input = 0;
iop->output = 0;
iop->flags = 0;
iop->input_timeout = timeout;
iop->bufsize = bufsize;
if ((flags & IO_READ) && (flags & IO_NEWSOCK) == 0)
iop->input = ioq_create(bufsize);
@ -106,31 +108,47 @@ io_close(struct iop *iop)
free(iop);
}
/*
* Return number of bytes read on success, zero on timeout or EOF, -1
* on error, with errno set appropriately. In particular, return -1
* with errno set to EAGAIN or EWOULDBLOCK when no data is available
* for non-blocking input (WAITFORINPUT false). Use io_eof() to
* distinguish timeout from EOF.
*/
int
io_input(struct iop *iop, int waitforinput)
{
char buf[IO_BUFSIZE];
int cc;
int res;
struct timeval timeout = iop->input_timeout;
/* Not a read IOP */
if ((iop->flags & IO_READ) == 0)
if ((iop->flags & IO_READ) == 0) {
errno = EBADF;
return -1;
}
/* IOP is markes as in error. */
if (iop->flags & IO_ERROR)
if (iop->flags & IO_ERROR) {
errno = EBADF;
return -1;
}
/* Wait for the file to have input. */
if (waitforinput) {
empth_select(iop->fd, EMPTH_FD_READ);
res = empth_select(iop->fd, EMPTH_FD_READ, &timeout);
if (res < 0) {
iop->flags |= IO_ERROR;
return -1;
} else if (res == 0)
return 0;
}
/* Do the actual read. */
cc = read(iop->fd, buf, sizeof(buf));
if (cc < 0) {
/* would block, so nothing to read. */
if (errno == EAGAIN || errno == EWOULDBLOCK)
return 0;
/* Some form of file error occurred... */
iop->flags |= IO_ERROR;
if (errno != EAGAIN && errno != EWOULDBLOCK)
/* Some form of file error occurred... */
iop->flags |= IO_ERROR;
return -1;
}
@ -190,7 +208,7 @@ io_output(struct iop *iop, int waitforoutput)
if (waitforoutput != IO_NOWAIT) {
/* This waits for the file to be ready for writing, */
/* and lets other threads run. */
empth_select(iop->fd, EMPTH_FD_WRITE);
empth_select(iop->fd, EMPTH_FD_WRITE, NULL);
}
/* Do the actual write. */
@ -272,7 +290,7 @@ io_output_all(struct iop *iop)
* a malicous player could delay the update indefinitely
*/
while ((n = io_output(iop, IO_NOWAIT)) > 0 && !play_wrlock_wanted)
empth_select(iop->fd, EMPTH_FD_WRITE);
empth_select(iop->fd, EMPTH_FD_WRITE, NULL);
return n;
}