Move queue flush out of io.c
Player threads may only sleep under certain conditions. In
particular, they must not sleep while a command is being aborted by
the update or shutdown.
io.c should not know about that. Yet io_output_all() does, because it
needs to give up when update or shutdown interrupt it. The function
was introduced in Empire 2, but it didn't give up then. Fixed in
commit a7fa7dee
, v4.2.22. The fix dragged unwanted knowledge of
command abortion into io.c.
To clean up this mess, io_output_all() has to go.
First user is io_write(). io_write() automatically flushes the queue.
In wait-mode, it calls io_output_all() when the queue is longer than
the bufsize, to attempt flushing the queue completely. In
no-wait-mode, it calls io_output() every bufsize bytes. Except the
test for that is screwy, so it actually misses some of the flush
conditions.
The automatic flush makes io_write() differ from io_gets(), which is
ugly. It wasn't present in BSD Empire 1.1. Remove it again, dropping
io_write()'s last argument.
Flush the queue in its callers pr_player() and upr_player() instead.
Provide new io_output_if_queue_long() for them. Requires new struct
iop member last_out to keep track of queue growth. pr_player() and
upr_player() call repeatedly until it makes no more progress. This
flushes a bit less eagerly in wait-mode, and a bit more eagerly in
non-wait mode.
Second user is recvclient(). It needs to flush the queue before
potentially sleeping in io_input(). Do that with a simple loop around
io_output(). No functional change there.
This commit is contained in:
parent
7fd5b86990
commit
1b4496253d
4 changed files with 53 additions and 39 deletions
|
@ -233,9 +233,7 @@ pr_player(struct player *pl, int id, char *buf)
|
|||
p = strchr(bp, '\n');
|
||||
if (p != NULL) {
|
||||
len = (p - bp) + 1;
|
||||
io_write(pl->iop, bp, len,
|
||||
player == pl
|
||||
&& !(pl->command && (pl->command->c_flags & C_MOD)));
|
||||
io_write(pl->iop, bp, len);
|
||||
bp += len;
|
||||
pl->curid = -1;
|
||||
} else {
|
||||
|
@ -243,6 +241,14 @@ pr_player(struct player *pl, int id, char *buf)
|
|||
bp += len;
|
||||
}
|
||||
}
|
||||
|
||||
if (player == pl) {
|
||||
while (io_output_if_queue_long(pl->iop,
|
||||
!play_wrlock_wanted
|
||||
&& !(pl->command && (pl->command->c_flags & C_MOD)))
|
||||
> 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -286,15 +292,21 @@ upr_player(struct player *pl, int id, char *buf)
|
|||
}
|
||||
}
|
||||
if (ch == '\n') {
|
||||
io_write(pl->iop, &ch, 1,
|
||||
player == pl
|
||||
&& !(pl->command && (pl->command->c_flags & C_MOD)));
|
||||
io_write(pl->iop, &ch, 1);
|
||||
pl->curid = -1;
|
||||
} else {
|
||||
printbuf[0] = ch;
|
||||
io_puts(pl->iop, printbuf);
|
||||
}
|
||||
}
|
||||
|
||||
if (player == pl) {
|
||||
while (io_output_if_queue_long(pl->iop,
|
||||
!play_wrlock_wanted
|
||||
&& !(pl->command && (pl->command->c_flags & C_MOD)))
|
||||
> 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue