summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-10-29 23:04:58 -0400
committerJune McEnroe <june@causal.agency>2019-10-29 23:04:58 -0400
commiteeac134e697f77d85ecbb8d6bd572a4b592433aa (patch)
tree611c18cdc27f146aa96ec3f5c652dd4fc0466ea2
parentDo not duplicate origin on nick change (diff)
downloadpounce-eeac134e697f77d85ecbb8d6bd572a4b592433aa.tar.gz
pounce-eeac134e697f77d85ecbb8d6bd572a4b592433aa.zip
Allocate ring buffer at runtime
-rw-r--r--bounce.c4
-rw-r--r--bounce.h1
-rw-r--r--ring.c36
3 files changed, 25 insertions, 16 deletions
diff --git a/bounce.c b/bounce.c
index 79a75f2..2a7acd4 100644
--- a/bounce.c
+++ b/bounce.c
@@ -180,11 +180,11 @@ int main(int argc, char *argv[]) {
 	if (!user) user = nick;
 	if (!real) real = nick;
 
+	ringAlloc(4096);
 	if (save) saveLoad(save);
 
-	listenConfig(certPath, privPath);
-
 	int bind[8];
+	listenConfig(certPath, privPath);
 	size_t binds = listenBind(bind, 8, bindHost, bindPort);
 
 	int server = serverConnect(insecure, host, port);
diff --git a/bounce.h b/bounce.h
index c37ff61..5e6313b 100644
--- a/bounce.h
+++ b/bounce.h
@@ -59,6 +59,7 @@ static inline struct Message parse(char *line) {
 	return msg;
 }
 
+void ringAlloc(size_t len);
 void ringProduce(const char *line);
 size_t ringConsumer(const char *name);
 size_t ringDiff(size_t consumer);
diff --git a/ring.c b/ring.c
index 474a6e4..0fec6d0 100644
--- a/ring.c
+++ b/ring.c
@@ -23,18 +23,25 @@
 
 #include "bounce.h"
 
-enum { RingLen = 4096 };
-static_assert(!(RingLen & (RingLen - 1)), "power of two RingLen");
-
 static struct {
-	char *lines[RingLen];
-	time_t times[RingLen];
+	size_t len;
+	char **lines;
+	time_t *times;
 } ring;
 
+void ringAlloc(size_t len) {
+	if (len & (len - 1)) errx(EX_CONFIG, "ring length must be power of two");
+	ring.lines = calloc(len, sizeof(*ring.lines));
+	if (!ring.lines) err(EX_OSERR, "calloc");
+	ring.times = calloc(len, sizeof(*ring.times));
+	if (!ring.times) err(EX_OSERR, "calloc");
+	ring.len = len;
+}
+
 size_t producer;
 
 void ringProduce(const char *line) {
-	size_t i = producer++ % RingLen;
+	size_t i = producer++ & (ring.len - 1);
 	if (ring.lines[i]) free(ring.lines[i]);
 	ring.times[i] = time(NULL);
 	ring.lines[i] = strdup(line);
@@ -79,17 +86,18 @@ size_t ringDiff(size_t consumer) {
 
 const char *ringPeek(time_t *time, size_t consumer) {
 	if (!ringDiff(consumer)) return NULL;
-	if (ringDiff(consumer) > RingLen) {
-		consumers.ptr[consumer].pos = producer - RingLen;
+	if (ringDiff(consumer) > ring.len) {
+		consumers.ptr[consumer].pos = producer - ring.len;
 	}
-	size_t i = consumers.ptr[consumer].pos % RingLen;
+	size_t i = consumers.ptr[consumer].pos & (ring.len - 1);
 	if (time) *time = ring.times[i];
+	assert(ring.lines[i]);
 	return ring.lines[i];
 }
 
 const char *ringConsume(time_t *time, size_t consumer) {
 	const char *line = ringPeek(time, consumer);
-	consumers.ptr[consumer].pos++;
+	if (line) consumers.ptr[consumer].pos++;
 	return line;
 }
 
@@ -124,10 +132,10 @@ int ringSave(FILE *file) {
 		if (writeString(file, consumers.ptr[i].name)) return -1;
 		if (writeSize(file, consumers.ptr[i].pos)) return -1;
 	}
-	for (size_t i = 0; i < RingLen; ++i) {
+	for (size_t i = 0; i < ring.len; ++i) {
 		if (writeTime(file, ring.times[i])) return -1;
 	}
-	for (size_t i = 0; i < RingLen; ++i) {
+	for (size_t i = 0; i < ring.len; ++i) {
 		if (!ring.lines[i]) break;
 		if (writeString(file, ring.lines[i])) return -1;
 	}
@@ -169,10 +177,10 @@ void ringLoad(FILE *file) {
 		readSize(file, &consumers.ptr[consumer].pos);
 	}
 
-	for (size_t i = 0; i < RingLen; ++i) {
+	for (size_t i = 0; i < ring.len; ++i) {
 		readTime(file, &ring.times[i]);
 	}
-	for (size_t i = 0; i < RingLen; ++i) {
+	for (size_t i = 0; i < ring.len; ++i) {
 		readString(file, &buf, &cap);
 		if (feof(file)) break;
 		ring.lines[i] = strdup(buf);