commit 3f8a18907d21e9e1a91799243d0ec86d5f948bd0
parent 3576211e4e1822a07fca3d2342427229726287d3
Author: quantumish <freifeld.david@gmail.com>
Date: Sat, 15 Apr 2023 23:01:17 -0700
Start trying to split listen() logic to a thread, attempt bugfixes
Diffstat:
5 files changed, 63 insertions(+), 34 deletions(-)
diff --git a/http.c b/http.c
@@ -21,10 +21,13 @@
#include "utils/log.h"
#include "utils/time.h"
#include "utils/shitvec.h"
+#include "utils/sync.h"
+
#include "utils/compress.h"
#include "http/response.h"
#include "http/request.h"
+
response_t serve_error(enum StatusCode c) {
response_t r = resp_new(c);
resp_add_hdr(&r, "Content-Type", "text/html");
@@ -155,7 +158,8 @@ void* handle_conn(void* ctxt) {
gettimeofday(&before, NULL);
if (msgbuf[0] != 0) {
request_t req = req_new(msgbuf, 1024);
-
+ log_debug("after init %p %p", req.headers.keys, req.headers.vals);
+
response_t r = make_response(req);
send(ns, r.content, r.sz, 0);
free(r.content);
@@ -188,23 +192,37 @@ int list_files_sv(shitvec_t* sv, char* base) {
return 0;
}
+channel_t listen_chan;
+
+void* listen_for_conns(void* ctxt) {
+ int s = *(int*)ctxt;
+ int namelen;
+ struct sockaddr_in client;
+ log_info("Hi!");
+ while (true) {
+ listen(s, 1);
+ int ns = accept(s, (struct sockaddr*)&client, (socklen_t*)&namelen);
+ log_info("Handling connection from %s", inet_ntoa(client.sin_addr));
+ channel_push(&listen_chan, &ns);
+ }
+}
+
// TODO some sort of DDOS protection idk
int main() {
int s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) die("socket");
+ int portnum = 8080;
struct sockaddr_in name;
name.sin_family = AF_INET;
- name.sin_port = htons(8082);
+ name.sin_port = htons(portnum);
name.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(s, (struct sockaddr*)&name, sizeof(name)) < 0) {
- name.sin_port = htons(0);
- if (bind(s, (struct sockaddr*)&name, sizeof(name)) < 0) {
- die("bind");
- }
- }
-
+ while(bind(s, (struct sockaddr*)&name, sizeof(name)) < 0) {
+ portnum += 1;
+ name.sin_port = htons(portnum);
+ }
+
paths = shitvec_new(MAX_PATH_LEN);
path_redirs = hashmap_new(MAX_PATH_LEN, MAX_PATH_LEN);
path_redirs.vark = true;
@@ -216,15 +234,14 @@ int main() {
getsockname(s, (struct sockaddr*)&name, (socklen_t*)&nlen);
log_debug("Open on port %d.", htons(name.sin_port));
- int namelen;
- char pathbuf[MAX_PATH_LEN];
- struct sockaddr_in client;
- char msgbuf[512] = {0};
- while (true) {
- listen(s, 1);
- int ns = accept(s, (struct sockaddr*)&client, (socklen_t*)&namelen);
+ listen_chan = channel_new(sizeof(int));
- log_info("Handling connection from %s", inet_ntoa(client.sin_addr));
+ pthread_t lthread;
+ pthread_create(&lthread, NULL, listen_for_conns, &s);
+ while (true) {
+ int ns = *(int*)channel_recv(&listen_chan);
+ log_debug("%d", ns);
+
pthread_t thread;
pthread_create(&thread, NULL, handle_conn, &ns);
}
diff --git a/http/request.c b/http/request.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
+#include <stdlib.h>
#include "../utils/log.h"
#include "request.h"
@@ -20,6 +21,8 @@ request_t req_new(char* reqbuf, size_t bufsize) {
request_t req;
req.buf = reqbuf;
req.bufsize = bufsize;
+ req.headers = hashmap_new(MAX_HEADER_NAME, MAX_HEADER_VALUE);
+ req.headers.vark = true;
return req;
}
@@ -61,9 +64,7 @@ int req_parse(request_t* req) {
int matched = sscanf(req->buf, "%s %s HTTP/%f\r\n", (char*)method, (char*)req->path, &req->ver);
if (matched < 3 || matched == EOF) return -1;
req->method = method_enum((char*)method);
-
- req->headers = hashmap_new(MAX_HEADER_NAME, MAX_HEADER_VALUE);
- req->headers.vark = true;
+
// FIXME if start is null this causes problems
char* start = memchr(req->buf, '\n', MAX_HEADER_NAME+MAX_HEADER_VALUE)+1;
while (start+MAX_HEADER_NAME+MAX_HEADER_VALUE < req->buf+req->bufsize) {
diff --git a/utils/hashmap.c b/utils/hashmap.c
@@ -41,6 +41,7 @@ hashmap_t hashmap_new(size_t ksize, size_t vsize) {
// Keys and vals are in different arrays so unnecessary things aren't in cache
h.keys = calloc(HASHMAP_INIT_SIZE, ksize);
h.vals = malloc(vsize * HASHMAP_INIT_SIZE);
+ log_debug("in init %p %p", h.keys, h.vals);
h.k_sz = ksize;
h.v_sz = vsize;
h.len = HASHMAP_INIT_SIZE;
diff --git a/utils/sync.c b/utils/sync.c
@@ -1,16 +1,6 @@
-
-#include <pthread.h>
-#include "shitvec.h"
-
-
-typedef struct channel {
- pthread_mutex_t mutex;
- shitvec_t queue;
- size_t msg_sz;
- size_t sz;
-} channel_t;
-
+#include "log.h"
+#include "sync.h"
channel_t channel_new(size_t msg_sz) {
channel_t out;
@@ -18,6 +8,7 @@ channel_t channel_new(size_t msg_sz) {
pthread_mutex_init(&out.mutex, NULL);
out.queue = shitvec_new(msg_sz);
out.sz = 0;
+ return out;
}
void channel_push(channel_t* chan, void* msg) {
@@ -38,6 +29,6 @@ void* channel_pop(channel_t* chan) {
}
void* channel_recv(channel_t * chan) {
- while (__atomic_load_n(&chan->sz, __ATOMIC_RELAXED) == 0);
- return channel_pop(chan);
+ while(__atomic_load_n(&chan->sz, __ATOMIC_RELAXED) == 0);
+ return channel_pop(chan);
}
diff --git a/utils/sync.h b/utils/sync.h
@@ -0,0 +1,19 @@
+#ifndef UTIL_SYNC_H
+#define UTIL_SYNC_H
+
+#include <pthread.h>
+#include "shitvec.h"
+
+typedef struct channel {
+ pthread_mutex_t mutex;
+ shitvec_t queue;
+ size_t msg_sz;
+ size_t sz;
+} channel_t;
+
+channel_t channel_new(size_t msg_sz);
+void channel_push(channel_t* chan, void* msg);
+void* channel_pop(channel_t* chan);
+void* channel_recv(channel_t * chan);
+
+#endif