Fix idle timeout during execute
Timeout during execute gets handled just like an EOF cookie: end the
batch file, resume reading normal commands. That's wrong, we need to
close the connection.
A real EOF is recorded in the player's connection's EOF indicator.
Let's use that for all "connection needs to be closed" conditions, so
they all work the same. Create io_set_eof() to provide access.
Make recvclient() set the player connection's EOF indicator on
timeout. This makes the timeout "stick". Record receipt of an EOF
cookie in new struct player member got_ctld. Also abort the command,
as before. This leaves further interpretation of the EOF cookie to
the command loops.
Make player_main() set the player connection's EOF indicator on
got_ctld. Player connection gets closed on on EOF cookie, as before.
Change execute() to break the batch command loop when got_ctld is set,
then reset it. Ends the batch file on EOF cookie, as before.
Change status() back to checking EOF and error indicators (partial
revert of commit 9c5854c8
, v4.3.16), and drop struct player member
eof.
This commit is contained in:
parent
d78d9cac1d
commit
ca7578f1b8
5 changed files with 38 additions and 20 deletions
|
@ -57,6 +57,7 @@ extern int io_puts(struct iop *, char *);
|
||||||
extern int io_shutdown(struct iop *, int);
|
extern int io_shutdown(struct iop *, int);
|
||||||
extern int io_error(struct iop *);
|
extern int io_error(struct iop *);
|
||||||
extern int io_eof(struct iop *);
|
extern int io_eof(struct iop *);
|
||||||
|
extern void io_set_eof(struct iop *);
|
||||||
extern int io_fileno(struct iop *);
|
extern int io_fileno(struct iop *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Dave Pare, 1994
|
* Dave Pare, 1994
|
||||||
* Doug Hay, 1998
|
* Doug Hay, 1998
|
||||||
* Markus Armbruster, 2005-2010
|
* Markus Armbruster, 2005-2012
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PLAYER_H
|
#ifndef PLAYER_H
|
||||||
|
@ -81,8 +81,8 @@ struct player {
|
||||||
double dolcost;
|
double dolcost;
|
||||||
time_t curup; /* when last input was received */
|
time_t curup; /* when last input was received */
|
||||||
enum player_sleep may_sleep; /* when may thread sleep? */
|
enum player_sleep may_sleep; /* when may thread sleep? */
|
||||||
int aborted; /* interrupt cookie or EOF received? */
|
int aborted; /* command aborted? */
|
||||||
int eof; /* EOF (cookie or real) received? */
|
int got_ctld; /* EOF cookie received? */
|
||||||
int recvfail; /* #recvclient() failures */
|
int recvfail; /* #recvclient() failures */
|
||||||
int curid; /* for pr, cur. line's id, -1 none */
|
int curid; /* for pr, cur. line's id, -1 none */
|
||||||
char *map; /* pointer to in-mem map */
|
char *map; /* pointer to in-mem map */
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Doug Hay, 1998
|
* Doug Hay, 1998
|
||||||
* Steve McClure, 1998
|
* Steve McClure, 1998
|
||||||
* Markus Armbruster, 2004-2010
|
* Markus Armbruster, 2004-2012
|
||||||
* Ron Koenderink, 2009
|
* Ron Koenderink, 2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -131,16 +131,17 @@ io_input(struct iop *iop, int waitforinput)
|
||||||
int cc;
|
int cc;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/* Not a read IOP */
|
|
||||||
if ((iop->flags & IO_READ) == 0) {
|
if ((iop->flags & IO_READ) == 0) {
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* IOP is markes as in error. */
|
|
||||||
if (iop->flags & IO_ERROR) {
|
if (iop->flags & IO_ERROR) {
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (iop->flags & IO_EOF)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Wait for the file to have input. */
|
/* Wait for the file to have input. */
|
||||||
if (waitforinput) {
|
if (waitforinput) {
|
||||||
res = empth_select(iop->fd, EMPTH_FD_READ, &iop->input_timeout);
|
res = empth_select(iop->fd, EMPTH_FD_READ, &iop->input_timeout);
|
||||||
|
@ -257,7 +258,6 @@ io_output_if_queue_long(struct iop *iop, int wait)
|
||||||
return io_output(iop, wait);
|
return io_output(iop, wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
io_peek(struct iop *iop, char *buf, int nbytes)
|
io_peek(struct iop *iop, char *buf, int nbytes)
|
||||||
{
|
{
|
||||||
|
@ -334,6 +334,17 @@ io_eof(struct iop *iop)
|
||||||
return iop->flags & IO_EOF;
|
return iop->flags & IO_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Discard IOP's buffered input and set its EOF flag.
|
||||||
|
* No more input can be read from IOP.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
io_set_eof(struct iop *iop)
|
||||||
|
{
|
||||||
|
ioq_drain(iop->input);
|
||||||
|
iop->flags |= IO_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
io_fileno(struct iop *iop)
|
io_fileno(struct iop *iop)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Steve McClure, 2000
|
* Steve McClure, 2000
|
||||||
* Markus Armbruster, 2004-2011
|
* Markus Armbruster, 2004-2012
|
||||||
* Ron Koenderink, 2004-2009
|
* Ron Koenderink, 2004-2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -99,7 +99,9 @@ player_main(struct player *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (status() && command()) {
|
while (status() && command()) {
|
||||||
player->aborted = player->eof;
|
if (player->got_ctld)
|
||||||
|
io_set_eof(player->iop);
|
||||||
|
player->aborted = 0;
|
||||||
empth_yield();
|
empth_yield();
|
||||||
}
|
}
|
||||||
/* #*# I put the following line in to prevent server crash -KHS */
|
/* #*# I put the following line in to prevent server crash -KHS */
|
||||||
|
@ -171,7 +173,8 @@ status(void)
|
||||||
|
|
||||||
time(&player->curup);
|
time(&player->curup);
|
||||||
update_timeused(player->curup);
|
update_timeused(player->curup);
|
||||||
if (player->eof || player->state == PS_SHUTDOWN
|
if (io_error(player->iop) || io_eof(player->iop)
|
||||||
|
|| player->state == PS_SHUTDOWN
|
||||||
|| !may_play_now(natp, player->curup))
|
|| !may_play_now(natp, player->curup))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -243,7 +246,7 @@ execute(void)
|
||||||
return RET_SYN;
|
return RET_SYN;
|
||||||
prexec(p);
|
prexec(p);
|
||||||
|
|
||||||
while (!failed && status()) {
|
while (!failed && status() && !player->got_ctld) {
|
||||||
player->nstat &= ~EXEC;
|
player->nstat &= ~EXEC;
|
||||||
if (getcommand(player->combuf) < 0)
|
if (getcommand(player->combuf) < 0)
|
||||||
break;
|
break;
|
||||||
|
@ -267,7 +270,7 @@ execute(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
pr("Execute : %s\n", failed ? "aborted" : "terminated");
|
pr("Execute : %s\n", failed ? "aborted" : "terminated");
|
||||||
player->eof = 0;
|
player->got_ctld = 0;
|
||||||
return RET_OK;
|
return RET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Dave Pare, 1986
|
* Dave Pare, 1986
|
||||||
* Markus Armbruster, 2006-2009
|
* Markus Armbruster, 2006-2012
|
||||||
* Ron Koenderink, 2009
|
* Ron Koenderink, 2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -47,10 +47,12 @@
|
||||||
* This may block for input, yielding the processor. Flush buffered
|
* This may block for input, yielding the processor. Flush buffered
|
||||||
* output when blocking, to make sure player sees the prompt.
|
* output when blocking, to make sure player sees the prompt.
|
||||||
* If the player's connection has the I/O error or EOF indicator set,
|
* If the player's connection has the I/O error or EOF indicator set,
|
||||||
* or we block and time out, or the line is "ctld", set the player's
|
* or the line is "aborted", set the player's aborted flag and return
|
||||||
* eof and aborted flag and return -1.
|
|
||||||
* If the line is "aborted", set the player's aborted flag and return
|
|
||||||
* -1.
|
* -1.
|
||||||
|
* If we block and time out, set the EOF indicator on the player's
|
||||||
|
* connection, set the player's aborted flag, and return -1.
|
||||||
|
* If the line is "ctld", set the player's eof and aborted flag and
|
||||||
|
* return -1.
|
||||||
* Else return the length of the line.
|
* Else return the length of the line.
|
||||||
* Design bug: there is no way to indicate truncation of a long line.
|
* Design bug: there is no way to indicate truncation of a long line.
|
||||||
*/
|
*/
|
||||||
|
@ -66,7 +68,7 @@ recvclient(char *cmd, int size)
|
||||||
if (count >= 0) {
|
if (count >= 0) {
|
||||||
/* got it */
|
/* got it */
|
||||||
if (strcmp(cmd, "ctld") == 0)
|
if (strcmp(cmd, "ctld") == 0)
|
||||||
player->aborted = player->eof = 1;
|
player->aborted = player->got_ctld = 1;
|
||||||
if (strcmp(cmd, "aborted") == 0)
|
if (strcmp(cmd, "aborted") == 0)
|
||||||
player->aborted = 1;
|
player->aborted = 1;
|
||||||
journal_input(cmd);
|
journal_input(cmd);
|
||||||
|
@ -92,12 +94,13 @@ recvclient(char *cmd, int size)
|
||||||
if (res > 0)
|
if (res > 0)
|
||||||
;
|
;
|
||||||
else if (res < 0)
|
else if (res < 0)
|
||||||
player->aborted = player->eof = 1;
|
player->aborted = 1;
|
||||||
else if (io_eof(player->iop))
|
else if (io_eof(player->iop))
|
||||||
player->aborted = player->eof = 1;
|
player->aborted = 1;
|
||||||
else if (!player->aborted) {
|
else if (!player->aborted) {
|
||||||
pr_flash(player, "idle connection terminated\n");
|
pr_flash(player, "idle connection terminated\n");
|
||||||
player->aborted = player->eof = 1;
|
io_set_eof(player->iop);
|
||||||
|
player->aborted = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue