summaryrefslogtreecommitdiffhomepage
path: root/src/sblist.h
diff options
context:
space:
mode:
authorrofl0r <retnyg@gmx.net>2018-12-17 00:23:09 +0000
committerrofl0r <rofl0r@users.noreply.github.com>2019-12-21 00:43:45 +0000
commitb935dc85c3fca51de8e131d6aa2047f8a0404f0c (patch)
treeacd0539895d42a436dbe7b1b5cbb90071d5ffcaa /src/sblist.h
parent3a7aa1583488d11b264014de5edfe097209de59e (diff)
simplify codebase by using one thread/conn, instead of preforked procs
the existing codebase used an elaborate and complex approach for its parallelism: 5 different config file options, namely - MaxClients - MinSpareServers - MaxSpareServers - StartServers - MaxRequestsPerChild were used to steer how (and how many) parallel processes tinyproxy would spin up at start, how many processes at each point needed to be idle, etc. it seems all preforked processes would listen on the server port and compete with each other about who would get assigned the new incoming connections. since some data needs to be shared across those processes, a half- baked "shared memory" implementation was provided for this purpose. that implementation used to use files in the filesystem, and since it had a big FIXME comment, the author was well aware of how hackish that approach was. this entire complexity is now removed. the main thread enters a loop which polls on the listening fds, then spins up a new thread per connection, until the maximum number of connections (MaxClients) is hit. this is the only of the 5 config options left after this cleanup. since threads share the same address space, the code necessary for shared memory access has been removed. this means that the other 4 mentioned config option will now produce a parse error, when encountered. currently each thread uses a hardcoded default of 256KB per thread for the thread stack size, which is quite lavish and should be sufficient for even the worst C libraries, but people may want to tweak this value to the bare minimum, thus we may provide a new config option for this purpose in the future. i suspect that on heavily optimized C libraries such a musl, a stack size of 8-16 KB per thread could be sufficient. since the existing list implementation in vector.c did not provide a way to remove a single item from an existing list, i added my own list implementation from my libulz library which offers this functionality, rather than trying to add an ad-hoc, and perhaps buggy implementation to the vector_t list code. the sblist code is contained in an 80 line C file and as simple as it can get, while offering good performance and is proven bugfree due to years of use in other projects.
Diffstat (limited to 'src/sblist.h')
-rw-r--r--src/sblist.h92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/sblist.h b/src/sblist.h
new file mode 100644
index 0000000..02c33d7
--- /dev/null
+++ b/src/sblist.h
@@ -0,0 +1,92 @@
+#ifndef SBLIST_H
+#define SBLIST_H
+
+/* this file is part of libulz, as of commit 8ab361a27743aaf025323ee43b8b8876dc054fdd
+ modified for direct inclusion in tinyproxy, and for this purpose released under
+ the license of tinyproxy. */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+/*
+ * simple buffer list.
+ *
+ * this thing here is basically a generic dynamic array
+ * will realloc after every blockitems inserts
+ * can store items of any size.
+ *
+ * so think of it as a by-value list, as opposed to a typical by-ref list.
+ * you typically use it by having some struct on the stack, and pass a pointer
+ * to sblist_add, which will copy the contents into its internal memory.
+ *
+ */
+
+typedef struct {
+ size_t itemsize;
+ size_t blockitems;
+ size_t count;
+ size_t capa;
+ char* items;
+} sblist;
+
+#define sblist_getsize(X) ((X)->count)
+#define sblist_get_count(X) ((X)->count)
+#define sblist_empty(X) ((X)->count == 0)
+
+/* for dynamic style */
+sblist* sblist_new(size_t itemsize, size_t blockitems);
+void sblist_free(sblist* l);
+
+/*for static style*/
+void sblist_init(sblist* l, size_t itemsize, size_t blockitems);
+void sblist_free_items(sblist* l);
+
+/* accessors */
+void* sblist_get(sblist* l, size_t item);
+/* returns 1 on success, 0 on OOM */
+int sblist_add(sblist* l, void* item);
+int sblist_set(sblist* l, void* item, size_t pos);
+void sblist_delete(sblist* l, size_t item);
+char* sblist_item_from_index(sblist* l, size_t idx);
+int sblist_grow_if_needed(sblist* l);
+int sblist_insert(sblist* l, void* item, size_t pos);
+/* same as sblist_add, but returns list index of new item, or -1 */
+size_t sblist_addi(sblist* l, void* item);
+void sblist_sort(sblist *l, int (*compar)(const void *, const void *));
+/* insert element into presorted list, returns listindex of new entry or -1*/
+size_t sblist_insert_sorted(sblist* l, void* o, int (*compar)(const void *, const void *));
+
+#ifndef __COUNTER__
+#define __COUNTER__ __LINE__
+#endif
+
+#define __sblist_concat_impl( x, y ) x##y
+#define __sblist_macro_concat( x, y ) __sblist_concat_impl( x, y )
+#define __sblist_iterator_name __sblist_macro_concat(sblist_iterator, __COUNTER__)
+
+/* use with custom iterator variable */
+#define sblist_iter_counter(LIST, ITER, PTR) \
+ for(size_t ITER = 0; (PTR = sblist_get(LIST, ITER)), ITER < sblist_getsize(LIST); ITER++)
+
+/* use with custom iterator variable, which is predeclared */
+#define sblist_iter_counter2(LIST, ITER, PTR) \
+ for(ITER = 0; (PTR = sblist_get(LIST, ITER)), ITER < sblist_getsize(LIST); ITER++)
+
+/* use with custom iterator variable, which is predeclared and signed */
+/* useful for a loop which can delete items from the list, and then decrease the iterator var. */
+#define sblist_iter_counter2s(LIST, ITER, PTR) \
+ for(ITER = 0; (PTR = sblist_get(LIST, ITER)), ITER < (ssize_t) sblist_getsize(LIST); ITER++)
+
+
+/* uses "magic" iterator variable */
+#define sblist_iter(LIST, PTR) sblist_iter_counter(LIST, __sblist_iterator_name, PTR)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+