From 15f9f81b5a8398fefca023e90d8d1c168ecef620 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Fri, 30 Oct 2026 23:11:41 +0100 Subject: Introduce a fast path assuming that a tcp connection's payload already has arrived at accept time --- opentracker.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'opentracker.c') diff --git a/opentracker.c b/opentracker.c index ec92fe0..b47759e 100644 --- a/opentracker.c +++ b/opentracker.c @@ -190,29 +190,45 @@ static void handle_write(const int64_t sock) { http_close(sock); } +/* The fast path, assuming that the complete request has usually arrived by the time a + connection is accepted, so it is answered here outside the event loop. The more load + a tracker has, the more likely it is that by the time it accepts, the roundtrip to + the peer has completed. + If the request could not be completely handled, the stack cookie is promoted to heap + and the connection handed over to the event loop to finish */ static void handle_accept(const int64_t serversocket, struct ot_workstruct *ws) { - struct http_data *cookie; - int64_t sock; - ot_ip6 ip; - uint16_t port; + int64_t sock; + ot_ip6 ip; + uint16_t port; while ((sock = socket_accept(serversocket, ip, &port)) != -1) { + struct http_data cookie; + uint32_t generation; - if (!(cookie = (struct http_data *)calloc(1, sizeof(struct http_data)))) { - close((int)sock); - continue; - } - memcpy(cookie->ip, ip, sizeof(ot_ip6)); - cookie->interest = EVENT_IN; + memset(&cookie, 0, sizeof(cookie)); + memcpy(cookie.ip, ip, sizeof(ot_ip6)); + cookie.interest = EVENT_IN; + cookie.flag = STRUCT_HTTP_FLAG_ONSTACK; - if (event_add((int)sock, EVENT_IN, fdstate_open(sock, cookie, time_future_seconds(OT_CLIENT_TIMEOUT))) == -1) { + generation = fdstate_open(sock, &cookie, time_future_seconds(OT_CLIENT_TIMEOUT)); + if (!fdstate_claim((int)sock, generation)) { fdstate_close(sock); - free(cookie); - close((int)sock); + event_close((int)sock); continue; } stats_issue_event(ws, EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); + + handle_read(sock, ws); + + /* Gone already if it was answered and closed inline */ + if (fdstate_generation((int)sock) != generation) + continue; + + if (http_adopt(sock, &cookie) == -1) + http_close(sock); + else + fdstate_release((int)sock); } } -- cgit v1.3