penguin/tinyproxy

An L4 proxy designed to act as a tiny transparent shim

commit e542c9fd58d21d650631c0c6be9f1210d6d04f77

author斟酌 鵬兄 <tgckpg@gmail.com>
date2026-05-30T13:38:38Z
subjectSupport -w0 for auto determine worker count
commit e542c9fd58d21d650631c0c6be9f1210d6d04f77
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2026-05-30T13:38:38Z

    Support -w0 for auto determine worker count
---
 docs/tinyproxy.1.scd | 10 ++++++++--
 fuzz/README.md       |  2 --
 mk/common.mk         |  3 ++-
 src/tinyproxy.c      |  2 +-
 src/worker.c         | 13 +++++++++----
 5 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/docs/tinyproxy.1.scd b/docs/tinyproxy.1.scd
index 56c74a5..389b73e 100644
--- a/docs/tinyproxy.1.scd
+++ b/docs/tinyproxy.1.scd
@@ -32,8 +32,14 @@ Routes may be configured using a config file or directly from the command line w
 # OPTIONS
 
 *-w* <workers>
-	Number of worker threads. 0 = auto (one per CPU).
-	Default 1
+	Number of worker threads.
+
+	0 = auto
+
+	The main thread is not counted. For example, -w 1 creates
+	one worker thread and one main thread.
+
+	Default: 1
 
 *-c* <config>
 	Load configuration file.
diff --git a/fuzz/README.md b/fuzz/README.md
index 7fc1adf..8e28774 100755
--- a/fuzz/README.md
+++ b/fuzz/README.md
@@ -1,5 +1,3 @@
-#!/bin/bash
-
 macos
 
 Fuzz for 8 hours
diff --git a/mk/common.mk b/mk/common.mk
index 7d1f3f9..c499d5b 100644
--- a/mk/common.mk
+++ b/mk/common.mk
@@ -26,7 +26,8 @@ UNAME_S := $(shell uname)
 
 ifeq ($(UNAME_S),Darwin)
 STATIC ?= 0
-CFLAGS  += -pthread
+CFLAGS += -pthread
+CFLAGS += -Wno-gnu-zero-variadic-macro-arguments
 LDFLAGS += -Wl,-dead_strip
 TEST_FLAGS := CONCURRENCY=1000 TOTAL=1000 FD_LIMIT=2560
 else ifeq ($(OS),Windows_NT)
diff --git a/src/tinyproxy.c b/src/tinyproxy.c
index 691c7a0..105571e 100644
--- a/src/tinyproxy.c
+++ b/src/tinyproxy.c
@@ -99,7 +99,7 @@ int main(int argc, char **argv)
 				worker_count = (int)n;
 
 				if(worker_count == 0) {
-					worker_count = compat_cpu_count();
+					worker_count = compat_cpu_count() - 1;
 				}
 
 				break;
diff --git a/src/worker.c b/src/worker.c
index 126e272..0c3dcf0 100644
--- a/src/worker.c
+++ b/src/worker.c
@@ -235,6 +235,11 @@ void worker_join(struct worker *w)
 	w->started = false;
 }
 
+static int socket_is_valid(evutil_socket_t fd)
+{
+    return fd != (evutil_socket_t)EVUTIL_INVALID_SOCKET;
+}
+
 void worker_free(struct worker *w)
 {
 	struct accepted_client_node *node;
@@ -250,7 +255,7 @@ void worker_free(struct worker *w)
 	while (node) {
 		struct accepted_client_node *next = node->next;
 
-		if (node->client.fd != EVUTIL_INVALID_SOCKET) {
+		if (socket_is_valid(node->client.fd)) {
 			evutil_closesocket(node->client.fd);
 		}
 
@@ -263,12 +268,12 @@ void worker_free(struct worker *w)
 		w->notify_event = NULL;
 	}
 
-	if (w->notify_recv_fd != EVUTIL_INVALID_SOCKET) {
+	if (socket_is_valid(w->notify_recv_fd)) {
 		evutil_closesocket(w->notify_recv_fd);
 		w->notify_recv_fd = EVUTIL_INVALID_SOCKET;
 	}
 
-	if (w->notify_send_fd != EVUTIL_INVALID_SOCKET) {
+	if (socket_is_valid(w->notify_send_fd)) {
 		evutil_closesocket(w->notify_send_fd);
 		w->notify_send_fd = EVUTIL_INVALID_SOCKET;
 	}
@@ -291,7 +296,7 @@ int worker_enqueue_client_fd(
 	struct accepted_client_node *node;
 	int rc;
 
-	if (!w || !route || fd == EVUTIL_INVALID_SOCKET) {
+	if (!w || !route || !socket_is_valid(fd)) {
 		return EINVAL;
 	}