Fix CPU pin if clients don't shutdown() their socket properly.

If we haven't read any bytes yet, then we try a few times a few ms apart
to see if we get anything. If not, treat it as an EOF. Otherwise, read
bytes until we get an EOF or EAGAIN. EAGAIN after a consistent read of
bytes is treaded as an EOF immediately.
This commit is contained in:
Jordan Bancino 2023-03-12 15:08:50 +00:00
parent 62cd1cdc98
commit 76bfa120ee

View file

@ -25,6 +25,7 @@
#include <Memory.h> #include <Memory.h>
#include <Str.h> #include <Str.h>
#include <Util.h>
#include <stdio.h> #include <stdio.h>
#include <stddef.h> #include <stddef.h>
@ -705,7 +706,12 @@ JsonFree(HashMap * object)
static int static int
JsonConsumeWhitespace(JsonParserState * state) JsonConsumeWhitespace(JsonParserState * state)
{ {
static const int nRetries = 5;
static const int delay = 2;
int c; int c;
int tries = 0;
int readFlg = 0;
while (1) while (1)
{ {
@ -721,7 +727,17 @@ JsonConsumeWhitespace(JsonParserState * state)
if (errno == EAGAIN) if (errno == EAGAIN)
{ {
clearerr(state->stream); clearerr(state->stream);
continue; tries++;
if (tries >= nRetries || readFlg)
{
break;
}
else
{
UtilSleepMillis(delay);
continue;
}
} }
else else
{ {
@ -729,6 +745,13 @@ JsonConsumeWhitespace(JsonParserState * state)
} }
} }
/* As soon as we've successfully read a byte, treat
* future EAGAINs as EOF, because some clients don't
* properly shutdown their sockets.
*/
readFlg = 1;
tries = 0;
if (!isspace(c)) if (!isspace(c))
{ {
break; break;