@@ -34,6 +34,10 @@ pub const AsyncIOType = @import("tardy").AsyncIOType;
3434const TardyCreator = @import ("tardy" ).Tardy ;
3535const Cross = @import ("tardy" ).Cross ;
3636
37+ const AcceptResult = @import ("tardy" ).AcceptResult ;
38+ const RecvResult = @import ("tardy" ).RecvResult ;
39+ const SendResult = @import ("tardy" ).SendResult ;
40+
3741pub const RecvStatus = union (enum ) {
3842 kill ,
3943 recv ,
@@ -278,21 +282,24 @@ pub fn Server(comptime security: Security, comptime AppState: type) type {
278282 }
279283 }
280284
281- fn accept_task (rt : * Runtime , child_socket : std.posix.socket_t , socket : std.posix.socket_t ) ! void {
282- const pool = rt .storage .get_ptr ("__zzz_provision_pool" , Pool (Provision ));
285+ fn accept_task (rt : * Runtime , result : AcceptResult , socket : std.posix.socket_t ) ! void {
283286 const accept_queued = rt .storage .get_ptr ("__zzz_accept_queued" , bool );
287+
288+ const child_socket = result .unwrap () catch | e | {
289+ log .err ("socket accept failed | {}" , .{e });
290+ accept_queued .* = true ;
291+ try rt .net .accept (socket , accept_task , socket );
292+ return ;
293+ };
294+
295+ const pool = rt .storage .get_ptr ("__zzz_provision_pool" , Pool (Provision ));
284296 accept_queued .* = false ;
285297
286298 if (rt .scheduler .tasks .clean () >= 2 ) {
287299 accept_queued .* = true ;
288300 try rt .net .accept (socket , accept_task , socket );
289301 }
290302
291- if (! Cross .socket .is_valid (child_socket )) {
292- log .err ("socket accept failed" , .{});
293- return error .AcceptFailed ;
294- }
295-
296303 // This should never fail. It means that we have a dangling item.
297304 assert (pool .clean () > 0 );
298305 const borrowed = pool .borrow () catch unreachable ;
@@ -339,7 +346,7 @@ pub fn Server(comptime security: Security, comptime AppState: type) type {
339346 };
340347
341348 provision .job = .{ .handshake = .{ .state = .recv , .count = 0 } };
342- try rt .net .recv (borrowed .item , handshake_task , child_socket , recv_buf );
349+ try rt .net .recv (borrowed .item , handshake_recv_task , child_socket , recv_buf );
343350 },
344351 .plain = > {
345352 provision .job = .{ .recv = .{ .count = 0 } };
@@ -348,8 +355,18 @@ pub fn Server(comptime security: Security, comptime AppState: type) type {
348355 }
349356 }
350357
351- fn recv_task (rt : * Runtime , length : i32 , provision : * Provision ) ! void {
358+ fn recv_task (rt : * Runtime , result : RecvResult , provision : * Provision ) ! void {
352359 assert (provision .job == .recv );
360+
361+ const length = result .unwrap () catch | e | {
362+ if (e != error .Closed ) {
363+ log .warn ("socket recv failed | {}" , .{e });
364+ }
365+ provision .job = .close ;
366+ try rt .net .close (provision , close_task , provision .socket );
367+ return ;
368+ };
369+
353370 const config = rt .storage .get_const_ptr ("__zzz_config" , ServerConfig );
354371 const router = rt .storage .get_const_ptr ("__zzz_router" , Router );
355372
@@ -424,7 +441,37 @@ pub fn Server(comptime security: Security, comptime AppState: type) type {
424441 }
425442 }
426443
427- fn handshake_task (rt : * Runtime , length : i32 , provision : * Provision ) ! void {
444+ fn handshake_recv_task (rt : * Runtime , result : RecvResult , provision : * Provision ) ! void {
445+ assert (security == .tls );
446+
447+ const length = result .unwrap () catch | e | {
448+ if (e != error .Closed ) {
449+ log .warn ("socket recv failed | {}" , .{e });
450+ }
451+ provision .job = .close ;
452+ try rt .net .close (provision , close_task , provision .socket );
453+ return error .TLSHandshakeClosed ;
454+ };
455+
456+ try handshake_inner_task (rt , length , provision );
457+ }
458+
459+ fn handshake_send_task (rt : * Runtime , result : SendResult , provision : * Provision ) ! void {
460+ assert (security == .tls );
461+
462+ const length = result .unwrap () catch | e | {
463+ if (e != error .ConnectionReset ) {
464+ log .warn ("socket send failed | {}" , .{e });
465+ }
466+ provision .job = .close ;
467+ try rt .net .close (provision , close_task , provision .socket );
468+ return error .TLSHandshakeClosed ;
469+ };
470+
471+ try handshake_inner_task (rt , length , provision );
472+ }
473+
474+ fn handshake_inner_task (rt : * Runtime , length : i32 , provision : * Provision ) ! void {
428475 assert (security == .tls );
429476 if (comptime security == .tls ) {
430477 const tls_slice = rt .storage .get ("__zzz_tls_slice" , []TLSType );
@@ -437,13 +484,6 @@ pub fn Server(comptime security: Security, comptime AppState: type) type {
437484 log .debug ("processing handshake" , .{});
438485 handshake_job .count += 1 ;
439486
440- if (length <= 0 ) {
441- log .debug ("handshake connection closed" , .{});
442- provision .job = .close ;
443- try rt .net .close (provision , close_task , provision .socket );
444- return error .TLSHandshakeClosed ;
445- }
446-
447487 if (handshake_job .count >= 50 ) {
448488 log .debug ("handshake taken too many cycles" , .{});
449489 provision .job = .close ;
@@ -467,12 +507,12 @@ pub fn Server(comptime security: Security, comptime AppState: type) type {
467507 .recv = > | buf | {
468508 log .debug ("queueing recv in handshake" , .{});
469509 handshake_job .state = .recv ;
470- try rt .net .recv (provision , handshake_task , provision .socket , buf );
510+ try rt .net .recv (provision , handshake_recv_task , provision .socket , buf );
471511 },
472512 .send = > | buf | {
473513 log .debug ("queueing send in handshake" , .{});
474514 handshake_job .state = .send ;
475- try rt .net .send (provision , handshake_task , provision .socket , buf );
515+ try rt .net .send (provision , handshake_send_task , provision .socket , buf );
476516 },
477517 .complete = > {
478518 log .debug ("handshake complete" , .{});
@@ -575,17 +615,21 @@ pub fn Server(comptime security: Security, comptime AppState: type) type {
575615 }
576616 }.inner );
577617
578- pub fn send_then (comptime func : TaskFn (bool , * Provision )) TaskFn (i32 , * Provision ) {
618+ pub fn send_then (comptime func : TaskFn (bool , * Provision )) TaskFn (SendResult , * Provision ) {
579619 return struct {
580- fn send_then_inner (rt : * Runtime , length : i32 , provision : * Provision ) ! void {
620+ fn send_then_inner (rt : * Runtime , result : SendResult , provision : * Provision ) ! void {
581621 assert (provision .job == .send );
582622 const config = rt .storage .get_const_ptr ("__zzz_config" , ServerConfig );
583623
584- // If the socket is closed.
585- if (length <= 0 ) {
586- try @call (.always_inline , func , .{ rt , false , provision });
624+ const length = result .unwrap () catch | e | {
625+ // If the socket is closed.
626+ if (e != error .ConnectionReset ) {
627+ log .warn ("socket send failed: {}" , .{e });
628+ }
629+
630+ try @call (.auto , func , .{ rt , false , provision });
587631 return ;
588- }
632+ };
589633
590634 const send_job = & provision .job .send ;
591635
0 commit comments