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:
Markus Armbruster 2009-04-27 23:23:30 +02:00
parent 7fd5b86990
commit 1b4496253d
4 changed files with 53 additions and 39 deletions

View file

@ -49,10 +49,10 @@ extern int io_input(struct iop *, int);
extern int io_inputwaiting(struct iop *);
extern int io_outputwaiting(struct iop *);
extern int io_output(struct iop *, int);
extern int io_output_if_queue_long(struct iop *, int);
extern int io_peek(struct iop *, char *, int);
extern int io_read(struct iop *, char *, int);
extern int io_write(struct iop *, char *, int, int);
extern int io_output_all(struct iop *);
extern int io_write(struct iop *, char *, int);
extern int io_gets(struct iop *, char *, int);
extern int io_puts(struct iop *, char *);
extern int io_shutdown(struct iop *, int);