summaryrefslogtreecommitdiff
path: root/trackerlogic.c
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2026-10-31 15:59:41 +0100
committerDirk Engling <erdgeist@erdgeist.org>2026-10-31 15:59:41 +0100
commit4d030871c004c917458b5e1c296edcfc689a2e66 (patch)
treec6c057e47a17d8b03ea28a611ff029d950acfa8c /trackerlogic.c
parent440cfeee71829308fa1cc9b5aef63beb7ab756dc (diff)
Make tcp worker multithreaded, too
This shamelessly steals the model established in the UDP workers, i.e. if the kernel is able to bind multiple listening sockets to the same endpoint, we will share them across threads. If it can't, all threads will accept on the same socket. The fast path handles most of the connections, only the rare case of no data yet on the socket is offloaded to the slow path (which used to be the mainloop) for completion. This scales nicely, as the higher the load is, the higher chances are that an accept happens only after the network roundtrip to the peer completes, leading to more connections that already have data waiting for us. We also consolidate the workstruct init and deinit code, preparation for later unifying all thread state structs for all protocols (mca, udc and tcp). The config file gains a per tcp connection worker count and some docs explaining what this knob buys and costs, nudging the user to either keep it 0 or dial it up to at least 2.
Diffstat (limited to 'trackerlogic.c')
-rw-r--r--trackerlogic.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/trackerlogic.c b/trackerlogic.c
index 477c4a6..fc0fa56 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -567,6 +567,35 @@ void trackerlogic_init(void) {
567 stats_init(); 567 stats_init();
568} 568}
569 569
570int workstruct_init(struct ot_workstruct *ws) {
571 memset(ws, 0, sizeof(*ws));
572 ws->inbuf = malloc(G_INBUF_SIZE);
573 ws->outbuf = malloc(G_OUTBUF_SIZE);
574#ifdef _DEBUG_HTTPERROR
575 ws->debugbuf = malloc(G_DEBUGBUF_SIZE);
576#endif
577 if (!ws->inbuf || !ws->outbuf)
578 return -1;
579
580 /* Picking which peers to hand out starts here, so two workers seeded alike
581 would hand out alike */
582 random_bytes(ws->rand48_state, sizeof(ws->rand48_state));
583
584 stats_counters_register(ws);
585 return 0;
586}
587
588void workstruct_deinit(struct ot_workstruct *ws) {
589 /* The tally goes to the global before this struct goes out of scope */
590 stats_counters_retire(ws);
591
592 free(ws->inbuf);
593 free(ws->outbuf);
594#ifdef _DEBUG_HTTPERROR
595 free(ws->debugbuf);
596#endif
597}
598
570void trackerlogic_deinit(void) { 599void trackerlogic_deinit(void) {
571 int delta_torrentcount = 0; 600 int delta_torrentcount = 0;
572 size_t bucket, j; 601 size_t bucket, j;