feat: std.http pooled handler dispatch (PLAN-HTTPZ S7b)

thread_pool_count = 0 (default) keeps handlers inline on the loop
thread — the measured fast path (BENCH-HTTPZ.md). N > 0 dispatches
each parsed request to a std.thread Pool of N workers, completing the
httpz two-pool shape: the connection freezes as CONN_HANDLING (no
reads, growth, eviction, or recycling — the worker borrows views into
its read buffer), the worker runs the handler under a per-job arena
and serializes into job-owned bytes, the completion queues under the
PoolState mutex, and the loop wakes through the new std.event wake
channel (kqueue EVFILT_USER + EV_CLEAR; the epoll twin maps to
eventfd), attaches the response, compacts the buffer, and resumes
keep-alive/pipeline handling. A full backlog sheds with 503. Stale
completions (generation mismatch after close) are dropped. Pool mode
requires the server's constructing allocator to be thread-safe
(GPA/malloc), documented on the knob.

PoolState lives behind a heap pointer (it embeds a Mutex and is shared
with workers; the Server struct itself is returned by value).
serialize_response/run_handler_job share one serialize_bytes.

examples/1633 gains the pooled section (GET, body echo, 404 across
worker threads) plus the loop-wake path exercised end to end; AOT run
five times. examples/1632 unchanged but the Event struct gains `user`.
This commit is contained in:
agra
2026-06-12 22:31:27 +03:00
parent 7f23bb7530
commit e57a27205e
42 changed files with 95852 additions and 81382 deletions

View File

@@ -39,18 +39,22 @@ contains :: (hay: string, needle: string) -> bool {
}
// Connect a nonblocking loopback client.
dial :: () -> i32 {
dial_port :: (port: i64) -> i32 {
fd := socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0);
if fd < 0 { return -1; }
addr : socket.SockAddr = .{
sin_len = 16, sin_family = xx socket.AF_INET,
sin_port = socket.htons(PORT), sin_addr = 0x0100007F,
sin_port = socket.htons(port), sin_addr = 0x0100007F,
};
if socket.connect(fd, @addr, 16) != 0 { socket.close(fd); return -1; }
if !socket.set_nonblocking(fd) { socket.close(fd); return -1; }
return fd;
}
dial :: () -> i32 {
return dial_port(PORT);
}
// True when `buf[0..len]` holds a complete response (headers + body).
resp_complete :: (buf: [*]u8, len: i64) -> bool {
s := string.{ ptr = buf, len = xx len };
@@ -210,6 +214,36 @@ main :: () -> i32 {
print("slow client evicted, healthy client served\n");
srv.close();
// ── pooled dispatch (S7b): same contract through worker threads ──
// thread_pool_count > 0 runs handlers on a pool; completions come
// back through the loop's wake channel. Same assertions: routing,
// body echo, keep-alive reuse — now crossing threads per request.
pcfg : http.Config = .{
port = PORT + 1,
timeout_request_ms = 1000,
timeout_keepalive_ms = 1000,
request_count = 50,
max_conn = 8,
thread_pool_count = 2,
thread_pool_backlog = 16,
};
psrv, pse := http.Server.init(pcfg, handler, 77);
if pse { print("pooled server init failed\n"); return 1; }
c5 := dial_port(PORT + 1);
if c5 < 0 { print("dial5 failed\n"); return 1; }
r7 := roundtrip(@psrv, c5, "GET /hello HTTP/1.1\r\nHost: t\r\n\r\n", @buf[0]);
if !contains(r7, "HTTP/1.1 200 OK") { print("pooled: bad status\n"); return 1; }
if !contains(r7, "hello GET") { print("pooled: bad body\n"); return 1; }
r8 := roundtrip(@psrv, c5, "POST /echo HTTP/1.1\r\nHost: t\r\nContent-Length: 9\r\n\r\nping-pong", @buf[0]);
if !contains(r8, "ping-pong") { print("pooled: echo failed\n"); return 1; }
r9 := roundtrip(@psrv, c5, "GET /missing HTTP/1.1\r\nHost: t\r\n\r\n", @buf[0]);
if !contains(r9, "HTTP/1.1 404 Not Found") { print("pooled: expected 404\n"); return 1; }
socket.close(c5);
psrv.close();
print("pooled dispatch: GET, echo, 404 across worker threads ok\n");
print("http server ok\n");
return 0;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -875,6 +875,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -897,7 +903,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -932,6 +944,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1367,6 +1367,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1389,7 +1395,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1424,6 +1436,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1383,6 +1383,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1405,7 +1411,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1440,6 +1452,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

File diff suppressed because one or more lines are too long

View File

@@ -1359,6 +1359,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1381,7 +1387,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1416,6 +1428,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

File diff suppressed because one or more lines are too long

View File

@@ -1385,6 +1385,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1407,7 +1413,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1442,6 +1454,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1361,6 +1361,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1383,7 +1389,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1418,6 +1430,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1359,6 +1359,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1381,7 +1387,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1416,6 +1428,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1359,6 +1359,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1381,7 +1387,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1416,6 +1428,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1359,6 +1359,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1381,7 +1387,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1416,6 +1428,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1359,6 +1359,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1381,7 +1387,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1416,6 +1428,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1359,6 +1359,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1381,7 +1387,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1416,6 +1428,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1359,6 +1359,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1381,7 +1387,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1416,6 +1428,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1359,6 +1359,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1381,7 +1387,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1416,6 +1428,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -1359,6 +1359,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -1381,7 +1387,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -1416,6 +1428,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -882,6 +882,12 @@ declare i32 @Loop.add_write(ptr, ptr, i32, i64) #0
; Function Attrs: nounwind
declare void @Loop.del_write(ptr, ptr, i32) #0
; Function Attrs: nounwind
declare i32 @Loop.add_wake(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Loop.wake(ptr, ptr) #0
; Function Attrs: nounwind
declare [2 x i64] @Loop.wait(ptr, ptr, ptr, i64) #0
@@ -904,7 +910,13 @@ declare i1 @ascii_ieq(ptr, ptr, ptr) #0
declare ptr @reason_for(ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64 }, i32 }), ptr, ptr, ptr, i64) #0
declare void @run_handler_job(ptr, i64) #0
; Function Attrs: nounwind
declare [2 x i64] @serialize_bytes(ptr, ptr, i1, ptr) #0
; Function Attrs: nounwind
declare void @Server.init(ptr sret({ { { i64, i32, i64, i64, i64, i64, i64, i64, i64 }, { i32 }, i32, ptr, { ptr, ptr, ptr }, ptr, i64, ptr }, i32 }), ptr, ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.close(ptr, ptr) #0
@@ -939,6 +951,9 @@ declare i1 @Server.try_serve_one(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Server.serialize_response(ptr, ptr, i64, ptr, i1) #0
; Function Attrs: nounwind
declare void @Server.drain_completions(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Server.write_more(ptr, ptr, i64) #0

View File

@@ -5,4 +5,5 @@ POST echo ok
404 routing ok
big body grows the buffer and echoes intact
slow client evicted, healthy client served
pooled dispatch: GET, echo, 404 across worker threads ok
http server ok