From 49c24d7b78d728f84ab4932572914aab71ddbc1e Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 12 Jul 2008 22:41:52 -0400 Subject: [PATCH] Oops when player thread keeps reading input unsuccessfully Reading input fails after EOF and while the current command is aborted. Commands should detect that and fail. If a command neglects to do that in a loop, the loop can become infinite. This is especially bad after EOF, because then the client might not read output anymore. Output gets buffered until memory runs out. Mitigate such bugs by counting how many calls have failed in a row, oopsing on the 256th, and sleeping one minute from the 256th on. --- include/player.h | 1 + src/lib/player/recvclient.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/player.h b/include/player.h index 584c613f6..52edb3364 100644 --- a/include/player.h +++ b/include/player.h @@ -78,6 +78,7 @@ struct player { time_t curup; /* when last input was received */ int aborted; /* interrupt cookie received? */ int eof; /* EOF (cookie or real) received? */ + int recvfail; /* #recvclient() failures */ int curid; /* for pr, cur. line's id, -1 none */ char *map; /* pointer to in-mem map */ char *bmap; /* pointer to in-mem bmap */ diff --git a/src/lib/player/recvclient.c b/src/lib/player/recvclient.c index bda3c37a0..72730cee6 100644 --- a/src/lib/player/recvclient.c +++ b/src/lib/player/recvclient.c @@ -91,10 +91,19 @@ recvclient(char *cmd, int size) player->eof = 1; } - if (player->eof) - return -1; - if (player->aborted) - return -2; + if (player->aborted || player->eof) { + player->recvfail++; + if (player->recvfail > 255) { + /* + * Looks like the thread is stuck in a loop that fails to + * check errors; oops once, then slow it down drastically. + */ + CANT_HAPPEN(player->recvfail == 256); + empth_sleep(time(NULL) + 60); + } + return player->eof ? -1 : -2; + } + player->recvfail = 0; return count; } -- 2.43.0