diff --git a/src/lib/empthread/io.c b/src/lib/empthread/io.c index ef285a74..47a2b109 100644 --- a/src/lib/empthread/io.c +++ b/src/lib/empthread/io.c @@ -108,7 +108,16 @@ io_open(int fd, int flags, int bufsize, struct timeval timeout) void io_close(struct iop *iop) { + 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) { + ret = read(iop->fd, buf, sizeof(buf)); + if (ret <= 0) + break; + } if (iop->input) ioq_destroy(iop->input); if (iop->output) @@ -201,15 +210,15 @@ io_output(struct iop *iop, int wait) if (wait) ef_make_stale(); - if (!ioq_qsize(iop->output)) - return 0; - if ((iop->flags & IO_WRITE) == 0) return -1; if (iop->flags & IO_ERROR) return -1; + if (!ioq_qsize(iop->output)) + return 0; + if (wait) { res = empth_select(iop->fd, EMPTH_FD_WRITE, NULL); if (res == 0) diff --git a/src/lib/player/accept.c b/src/lib/player/accept.c index 70133ff8..87eb9124 100644 --- a/src/lib/player/accept.c +++ b/src/lib/player/accept.c @@ -100,14 +100,14 @@ player_delete(struct player *lp) { struct player *back; - back = (struct player *)lp->queue.q_back; - if (back) - emp_remque(&lp->queue); if (lp->iop) { /* it's a real player */ io_close(lp->iop); lp->iop = NULL; } + back = (struct player *)lp->queue.q_back; + if (back) + emp_remque(&lp->queue); free(lp); /* XXX may need to free bigmap here */ return back; diff --git a/src/lib/player/login.c b/src/lib/player/login.c index fc002149..1f5400c9 100644 --- a/src/lib/player/login.c +++ b/src/lib/player/login.c @@ -122,7 +122,6 @@ player_login(void *ud) } player->state = PS_SHUTDOWN; pr_id(player, C_EXIT, "so long...\n"); - while (io_output(player->iop, 1) > 0) ; player_delete(player); empth_exit(); /*NOTREACHED*/ diff --git a/src/server/main.c b/src/server/main.c index becfeb34..da02ccdf 100644 --- a/src/server/main.c +++ b/src/server/main.c @@ -411,7 +411,7 @@ shutdwn(int sig) { struct player *p; time_t now; - int i, queues_drained; + int i; logerror("Shutdown commencing (cleaning up threads.)"); @@ -431,22 +431,13 @@ shutdwn(int sig) now = time(NULL); empth_yield(); - for (i = 1; i <= 3; i++) { - queues_drained = 1; - for (p = player_next(NULL); p; p = player_next(p)) { - if (io_outputwaiting(p->iop)) - queues_drained = 0; - } - if (queues_drained) - break; - logerror("Waiting for player output to drain\n"); + for (i = 1; i <= 3 && player_next(NULL); i++) { + logerror("Waiting for player threads to terminate\n"); empth_sleep(now + i); } - for (p = player_next(NULL); p; p = player_next(p)) { - if (io_outputwaiting(p->iop)) - logerror("Output for player %d lost", p->cnum); - } + for (p = player_next(NULL); p; p = player_next(p)) + logerror("Player %d lingers, output might be lost", p->cnum); if (sig) logerror("Server shutting down on signal %d", sig);