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:
parent
a7ee69d112
commit
08b9455682
17 changed files with 181 additions and 133 deletions
|
@ -55,7 +55,10 @@ static fd_set LwpReadfds, LwpWritefds;
|
|||
/* Map file descriptor to thread sleeping in lwpSleepFd() */
|
||||
static struct lwpProc **LwpFdwait;
|
||||
|
||||
/* Threads sleeping in lwpSleepUntil(), in no particular order */
|
||||
/*
|
||||
* Threads sleeping until a wakeup time, in lwpSleepUntil() or
|
||||
* lwpSleepFd(), in no particular order
|
||||
*/
|
||||
static struct lwpQueue LwpDelayq;
|
||||
|
||||
/* The thread executing lwpSelect() */
|
||||
|
@ -74,23 +77,25 @@ lwpInitSelect(struct lwpProc *proc)
|
|||
LwpSelProc = proc;
|
||||
}
|
||||
|
||||
void
|
||||
lwpSleepFd(int fd, int mask)
|
||||
int
|
||||
lwpSleepFd(int fd, int mask, struct timeval *timeout)
|
||||
{
|
||||
lwpStatus(LwpCurrent, "sleeping on fd %d for %d", fd, mask);
|
||||
|
||||
if (CANT_HAPPEN(fd > FD_SETSIZE))
|
||||
return;
|
||||
if (CANT_HAPPEN(fd > FD_SETSIZE)) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (LwpFdwait[fd] != 0) {
|
||||
lwpStatus(LwpCurrent,
|
||||
"multiple sleeps attempted on file descriptor %d", fd);
|
||||
return;
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (mask & LWP_FD_READ)
|
||||
FD_SET(fd, &LwpReadfds);
|
||||
if (mask & LWP_FD_WRITE)
|
||||
FD_SET(fd, &LwpWritefds);
|
||||
|
||||
LwpNfds++;
|
||||
|
||||
if (LwpMaxfd == 0 && LwpDelayq.head == 0) {
|
||||
|
@ -99,20 +104,39 @@ lwpSleepFd(int fd, int mask)
|
|||
lwpReady(LwpSelProc);
|
||||
}
|
||||
lwpStatus(LwpCurrent, "going to wait on fd %d", fd);
|
||||
|
||||
if (timeout) {
|
||||
LwpCurrent->runtime = time(NULL) + timeout->tv_sec +
|
||||
(timeout->tv_usec > 0);
|
||||
lwpAddTail(&LwpDelayq, LwpCurrent);
|
||||
} else
|
||||
LwpCurrent->runtime = (time_t)-1;
|
||||
|
||||
if (fd > LwpMaxfd)
|
||||
LwpMaxfd = fd;
|
||||
LwpFdwait[fd] = LwpCurrent;
|
||||
LwpCurrent->fd = fd;
|
||||
LwpCurrent->fd_ready = 0;
|
||||
lwpReschedule();
|
||||
return LwpCurrent->fd_ready != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wake up PROC if it is sleeping in lwpSleepFd().
|
||||
* Must be followed by lwpWakeupSleep() before the next lwpReschedule().
|
||||
*/
|
||||
static void
|
||||
lwpWakeupFd(struct lwpProc *proc)
|
||||
{
|
||||
if (proc->fd < 0)
|
||||
if (CANT_HAPPEN(proc->fd < 0 || proc->fd > LwpMaxfd))
|
||||
return;
|
||||
|
||||
lwpStatus(proc, "awakening; was sleeping on fd %d", proc->fd);
|
||||
if (proc->runtime != (time_t)-1) {
|
||||
/* is in LwpDelayq; leave the job to lwpWakeupSleep() */
|
||||
proc->runtime = 0;
|
||||
return;
|
||||
}
|
||||
FD_CLR(proc->fd, &LwpReadfds);
|
||||
FD_CLR(proc->fd, &LwpWritefds);
|
||||
LwpNfds--;
|
||||
|
@ -121,6 +145,9 @@ lwpWakeupFd(struct lwpProc *proc)
|
|||
lwpReady(proc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wake up threads in LwpDelayq whose time has come.
|
||||
*/
|
||||
void
|
||||
lwpWakeupSleep(void)
|
||||
{
|
||||
|
@ -134,7 +161,11 @@ lwpWakeupSleep(void)
|
|||
while (NULL != (proc = lwpGetFirst(&LwpDelayq))) {
|
||||
if (now >= proc->runtime) {
|
||||
lwpStatus(proc, "sleep done");
|
||||
lwpReady(proc);
|
||||
proc->runtime = (time_t)-1;
|
||||
if (proc->fd >= 0)
|
||||
lwpWakeupFd(proc);
|
||||
else
|
||||
lwpReady(proc);
|
||||
} else {
|
||||
lwpAddTail(&save, proc);
|
||||
}
|
||||
|
@ -148,10 +179,9 @@ lwpWakeup(struct lwpProc *proc)
|
|||
{
|
||||
if (proc->fd >= 0)
|
||||
lwpWakeupFd(proc);
|
||||
else if (proc->runtime != (time_t)-1) {
|
||||
else if (proc->runtime != (time_t)-1)
|
||||
proc->runtime = 0;
|
||||
lwpWakeupSleep();
|
||||
}
|
||||
lwpWakeupSleep();
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -230,7 +260,6 @@ lwpSelect(void *arg)
|
|||
continue;
|
||||
}
|
||||
|
||||
lwpWakeupSleep();
|
||||
if (n > 0) {
|
||||
/* file descriptor activity */
|
||||
for (fd = 0; fd <= LwpMaxfd; fd++) {
|
||||
|
@ -238,16 +267,19 @@ lwpSelect(void *arg)
|
|||
continue;
|
||||
if (FD_ISSET(fd, &readmask)) {
|
||||
lwpStatus(LwpFdwait[fd], "input ready");
|
||||
LwpFdwait[fd]->fd_ready = 1;
|
||||
lwpWakeupFd(LwpFdwait[fd]);
|
||||
continue;
|
||||
}
|
||||
if (FD_ISSET(fd, &writemask)) {
|
||||
lwpStatus(LwpFdwait[fd], "output ready");
|
||||
LwpFdwait[fd]->fd_ready = 1;
|
||||
lwpWakeupFd(LwpFdwait[fd]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
lwpWakeupSleep();
|
||||
lwpStatus(us, "fd dispatch completed");
|
||||
lwpReady(LwpCurrent);
|
||||
lwpReschedule();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue