feat: std.http — single-worker HTTP/1.1 server core (PLAN-HTTPZ S7a)
The httpz shape, one worker, handlers inline over the std.event Loop: nonblocking accept, per-connection state machine (reading -> writing -> keepalive/close) with incremental parsing (request line, headers, Content-Length body), partial-write continuation via on-demand write interest, pipelined-request draining, and timeouts as EVICTION — request-delivery and keepalive-idle deadlines on the monotonic clock, checked after I/O each tick. Keep-alive is the HTTP/1.1 default; Connection header, HTTP/1.0, or the per-connection request_count cap turn it off. Config mirrors httpz: port/backlog/max_conn/read_buf_cap/ timeout_request_ms/timeout_keepalive_ms/request_count. API: Server.init(cfg, handler) + tick(max_wait_ms); run() is the forever-tick loop. tick makes the server drivable single-threaded — examples/1633 runs a live server and its client sockets in ONE thread, pinning: GET with keep-alive, actual connection reuse, the request cap answering Connection: close then EOF, POST body echo, 404 routing, and a half-header client evicted at the request deadline while a healthy client keeps being served. Verified under sx run AND sx build. Connection slots and read buffers are reused across connections (httpz's min_conn/buffer-pool spirit); response buffers are allocated per response and freed on completion. Serialization happens while request views are valid, the served bytes are compacted, and only then does sending start — write_more's pipelining check must see only the remainder. The std.sx barrel carries http; .ir snapshot regen is the usual mechanical renumbering. S7b adds worker counts + the handler thread pool (needs C2/S6); the epoll backend activates with the linux target (S4/S7c).
This commit is contained in:
@@ -1379,6 +1379,54 @@ declare i1 @expired(ptr, i64) #0
|
||||
; Function Attrs: nounwind
|
||||
declare i64 @remaining_ms(ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @find_header(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i1 @ascii_ieq(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
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 }, i32 }), ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.close(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i64 @Server.free_slot(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.conn_close(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @Server.tick(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.run(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.accept_ready(ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.read_more(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.serve_buffered(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
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.write_more(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Server.respond_error_close(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @BuildOptions.add_link_flag.77(i64, ptr) #0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user