Fix memory and connection closing errors.

This commit is contained in:
Jordan Bancino 2022-11-08 01:05:28 +00:00
parent 6c016b813c
commit efbbf42a6e
5 changed files with 63 additions and 38 deletions

View file

@ -48,7 +48,7 @@ struct DbRef
}; };
static ssize_t static ssize_t
DbComputeSize(HashMap *json) DbComputeSize(HashMap * json)
{ {
char *key; char *key;
JsonValue *val; JsonValue *val;

View file

@ -86,7 +86,7 @@ HashMapGrow(HashMap * map)
return 0; return 0;
} }
memset(&newEntries, 0, map->capacity * sizeof(HashMapBucket *)); memset(newEntries, 0, map->capacity * sizeof(HashMapBucket *));
for (i = 0; i < oldCapacity; i++) for (i = 0; i < oldCapacity; i++)
{ {

View file

@ -77,6 +77,13 @@ struct HttpServerContext
FILE *stream; FILE *stream;
}; };
typedef struct HttpServerWorkerThreadArgs
{
HttpServer *server;
int id;
pthread_t thread;
} HttpServerWorkerThreadArgs;
static HttpServerContext * static HttpServerContext *
HttpServerContextCreate(HttpRequestMethod requestMethod, HttpServerContextCreate(HttpRequestMethod requestMethod,
char *requestPath, HashMap * requestParams, FILE * stream) char *requestPath, HashMap * requestParams, FILE * stream)
@ -437,11 +444,12 @@ HttpServerFree(HttpServer * server)
static void * static void *
HttpServerWorkerThread(void *args) HttpServerWorkerThread(void *args)
{ {
HttpServer *server = (HttpServer *) args; HttpServerWorkerThreadArgs *wArgs = (HttpServerWorkerThreadArgs *) args;
HttpServer *server = wArgs->server;
while (!server->stop) while (!server->stop)
{ {
FILE *fp = DequeueConnection(server); FILE *fp;
HttpServerContext *context; HttpServerContext *context;
char *line = NULL; char *line = NULL;
@ -461,6 +469,10 @@ HttpServerWorkerThread(void *args)
ssize_t i = 0; ssize_t i = 0;
HttpRequestMethod requestMethod; HttpRequestMethod requestMethod;
long firstRead;
fp = DequeueConnection(server);
if (!fp) if (!fp)
{ {
/* Block for 1 millisecond before continuing so we don't /* Block for 1 millisecond before continuing so we don't
@ -476,11 +488,20 @@ HttpServerWorkerThread(void *args)
* EAGAIN, then clear the error on the stream and try again * EAGAIN, then clear the error on the stream and try again
* after 1ms. This is typically more than enough time for the * after 1ms. This is typically more than enough time for the
* client to send data. */ * client to send data. */
firstRead = UtilServerTs();
while ((lineLen = UtilGetLine(&line, &lineSize, fp, &lineError)) == -1 while ((lineLen = UtilGetLine(&line, &lineSize, fp, &lineError)) == -1
&& lineError == EAGAIN) && lineError == EAGAIN)
{ {
clearerr(fp); clearerr(fp);
UtilSleepMillis(1);
/* If the server is stopped, or it's been a while, just
* give up. */
if (server->stop || (UtilServerTs() - firstRead) > 1000 * 30)
{
goto finish;
}
UtilSleepMillis(5);
} }
if (lineLen == -1) if (lineLen == -1)
@ -652,7 +673,7 @@ HttpServerEventThread(void *args)
for (i = 0; i < server->nThreads; i++) for (i = 0; i < server->nThreads; i++)
{ {
pthread_t *workerThread = Malloc(sizeof(pthread_t)); HttpServerWorkerThreadArgs *workerThread = Malloc(sizeof(HttpServerWorkerThreadArgs));
if (!workerThread) if (!workerThread)
{ {
@ -661,7 +682,10 @@ HttpServerEventThread(void *args)
return NULL; return NULL;
} }
if (pthread_create(workerThread, NULL, HttpServerWorkerThread, server) != 0) workerThread->server = server;
workerThread->id = i;
if (pthread_create(&workerThread->thread, NULL, HttpServerWorkerThread, workerThread) != 0)
{ {
/* TODO: Make the event thread return an error to the main /* TODO: Make the event thread return an error to the main
* thread */ * thread */
@ -698,9 +722,9 @@ HttpServerEventThread(void *args)
for (i = 0; i < server->nThreads; i++) for (i = 0; i < server->nThreads; i++)
{ {
pthread_t *workerThread = ArrayGet(server->threadPool, i); HttpServerWorkerThreadArgs *workerThread = ArrayGet(server->threadPool, i);
pthread_join(*workerThread, NULL); pthread_join(workerThread->thread, NULL);
Free(workerThread); Free(workerThread);
} }

View file

@ -77,6 +77,8 @@ MatrixHttpHandler(HttpServerContext * context, void *argp)
HttpResponseHeader(context, "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); HttpResponseHeader(context, "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
HttpResponseHeader(context, "Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Authorization"); HttpResponseHeader(context, "Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Authorization");
HttpResponseHeader(context, "Connection", "close");
/* /*
* Web Browser Clients: Servers MUST expect that clients will approach them * Web Browser Clients: Servers MUST expect that clients will approach them
* with OPTIONS requests... the server MUST NOT perform any logic defined * with OPTIONS requests... the server MUST NOT perform any logic defined

View file

@ -98,7 +98,6 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc)
if (!directive) if (!directive)
{ {
Log(lc, LOG_WARNING, "No 'listen' directive specified; using default value, which may change.");
tConfig->listenPort = 8008; tConfig->listenPort = 8008;
} }
else else