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
|
@ -39,6 +39,7 @@
|
|||
#include "journal.h"
|
||||
#include "player.h"
|
||||
#include "prototypes.h"
|
||||
#include "server.h"
|
||||
|
||||
/*
|
||||
* Receive a line of input from the current player.
|
||||
|
@ -75,8 +76,11 @@ recvclient(char *cmd, int size)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Make sure player sees prompt */
|
||||
io_output_all(player->iop);
|
||||
/*
|
||||
* Flush all queued output before potentially sleeping in
|
||||
* io_input(), to make sure player sees the prompt.
|
||||
*/
|
||||
while (io_output(player->iop, !play_wrlock_wanted) > 0) ;
|
||||
|
||||
/*
|
||||
* If io_output_all() blocked and got unblocked by command
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue