From efbbf42a6e9ffe6cc97e21a0caa38f894532f61d Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Tue, 8 Nov 2022 01:05:28 +0000 Subject: [PATCH] Fix memory and connection closing errors. --- src/Db.c | 58 ++++++++++++++++++++--------------------- src/HashMap.c | 2 +- src/HttpServer.c | 38 ++++++++++++++++++++++----- src/Matrix.c | 2 ++ src/TelodendriaConfig.c | 1 - 5 files changed, 63 insertions(+), 38 deletions(-) diff --git a/src/Db.c b/src/Db.c index 5f43f1d..198984e 100644 --- a/src/Db.c +++ b/src/Db.c @@ -48,42 +48,42 @@ struct DbRef }; static ssize_t -DbComputeSize(HashMap *json) +DbComputeSize(HashMap * json) { - char *key; - JsonValue *val; - MemoryInfo *a; - size_t total; + char *key; + JsonValue *val; + MemoryInfo *a; + size_t total; - if (!json) - { - return -1; - } + if (!json) + { + return -1; + } - total = 0; + total = 0; - a = MemoryInfoGet(json); - if (a) - { - total += MemoryInfoGetSize(a); - } + a = MemoryInfoGet(json); + if (a) + { + total += MemoryInfoGetSize(a); + } - while (HashMapIterate(json, &key, (void **) &val)) - { - a = MemoryInfoGet(key); - if (a) - { - total += MemoryInfoGetSize(a); - } + while (HashMapIterate(json, &key, (void **) &val)) + { + a = MemoryInfoGet(key); + if (a) + { + total += MemoryInfoGetSize(a); + } - a = MemoryInfoGet(val); - if (a) - { - total += MemoryInfoGetSize(a); - } - } + a = MemoryInfoGet(val); + if (a) + { + total += MemoryInfoGetSize(a); + } + } - return total; + return total; } Db * diff --git a/src/HashMap.c b/src/HashMap.c index e09a5f7..0dffc04 100644 --- a/src/HashMap.c +++ b/src/HashMap.c @@ -86,7 +86,7 @@ HashMapGrow(HashMap * map) return 0; } - memset(&newEntries, 0, map->capacity * sizeof(HashMapBucket *)); + memset(newEntries, 0, map->capacity * sizeof(HashMapBucket *)); for (i = 0; i < oldCapacity; i++) { diff --git a/src/HttpServer.c b/src/HttpServer.c index 020c217..dfaab12 100644 --- a/src/HttpServer.c +++ b/src/HttpServer.c @@ -77,6 +77,13 @@ struct HttpServerContext FILE *stream; }; +typedef struct HttpServerWorkerThreadArgs +{ + HttpServer *server; + int id; + pthread_t thread; +} HttpServerWorkerThreadArgs; + static HttpServerContext * HttpServerContextCreate(HttpRequestMethod requestMethod, char *requestPath, HashMap * requestParams, FILE * stream) @@ -437,11 +444,12 @@ HttpServerFree(HttpServer * server) static void * HttpServerWorkerThread(void *args) { - HttpServer *server = (HttpServer *) args; + HttpServerWorkerThreadArgs *wArgs = (HttpServerWorkerThreadArgs *) args; + HttpServer *server = wArgs->server; while (!server->stop) { - FILE *fp = DequeueConnection(server); + FILE *fp; HttpServerContext *context; char *line = NULL; @@ -461,6 +469,10 @@ HttpServerWorkerThread(void *args) ssize_t i = 0; HttpRequestMethod requestMethod; + long firstRead; + + fp = DequeueConnection(server); + if (!fp) { /* 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 * after 1ms. This is typically more than enough time for the * client to send data. */ + firstRead = UtilServerTs(); while ((lineLen = UtilGetLine(&line, &lineSize, fp, &lineError)) == -1 && lineError == EAGAIN) { 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) @@ -652,7 +673,7 @@ HttpServerEventThread(void *args) for (i = 0; i < server->nThreads; i++) { - pthread_t *workerThread = Malloc(sizeof(pthread_t)); + HttpServerWorkerThreadArgs *workerThread = Malloc(sizeof(HttpServerWorkerThreadArgs)); if (!workerThread) { @@ -661,7 +682,10 @@ HttpServerEventThread(void *args) 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 * thread */ @@ -698,9 +722,9 @@ HttpServerEventThread(void *args) 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); } diff --git a/src/Matrix.c b/src/Matrix.c index 2589eb9..dedc2f4 100644 --- a/src/Matrix.c +++ b/src/Matrix.c @@ -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-Headers", "X-Requested-With, Content-Type, Authorization"); + HttpResponseHeader(context, "Connection", "close"); + /* * Web Browser Clients: Servers MUST expect that clients will approach them * with OPTIONS requests... the server MUST NOT perform any logic defined diff --git a/src/TelodendriaConfig.c b/src/TelodendriaConfig.c index a7fd9e5..ed009b0 100644 --- a/src/TelodendriaConfig.c +++ b/src/TelodendriaConfig.c @@ -98,7 +98,6 @@ TelodendriaConfigParse(HashMap * config, LogConfig * lc) if (!directive) { - Log(lc, LOG_WARNING, "No 'listen' directive specified; using default value, which may change."); tConfig->listenPort = 8008; } else