(pr_player, upr_player): Blocking I/O on another player's struct iop *

is unsafe!  By the time the blocked thread wakes up, that player may
be gone, along with its struct iop *, and io_write() follows a
dangling pointer.  Moreover, at most one thread may use empth_select()
on the same file descriptor.  Violations of that restriction cause
threads to hang under Windows since ntthread.c rev. 1.15.  Make all
output to another player non-blocking for now.  Historically, player
threads sent output only to their socket, though their own iop.  This
was broken by flash and asynchronous telegram notification a long time
ago.
This commit is contained in:
Ron Koenderink 2005-07-04 14:07:31 +00:00
parent 4ea137e887
commit 42a3ce3958

View file

@ -220,7 +220,8 @@ pr_player(struct player *pl, int id, char *buf)
p = strchr(bp, '\n'); p = strchr(bp, '\n');
if (p != NULL) { if (p != NULL) {
len = (p - bp) + 1; len = (p - bp) + 1;
if (pl->command && (pl->command->c_flags & C_MOD)) if ((pl->command && (pl->command->c_flags & C_MOD)) ||
(player != pl))
io_write(pl->iop, bp, len, IO_NOWAIT); io_write(pl->iop, bp, len, IO_NOWAIT);
else else
io_write(pl->iop, bp, len, IO_WAIT); io_write(pl->iop, bp, len, IO_WAIT);
@ -274,7 +275,8 @@ upr_player(struct player *pl, int id, char *buf)
} }
} }
if (ch == '\n') { if (ch == '\n') {
if (pl->command && (pl->command->c_flags & C_MOD)) if ((pl->command && (pl->command->c_flags & C_MOD)) ||
(player != pl))
io_write(pl->iop, &ch, 1, IO_NOWAIT); io_write(pl->iop, &ch, 1, IO_NOWAIT);
else else
io_write(pl->iop, &ch, 1, IO_WAIT); io_write(pl->iop, &ch, 1, IO_WAIT);