@@ -422,6 +422,13 @@ fn AsyncHandler(comptime H: type, comptime L: type) type {
422422 // that we have valid, but unprocessed, data up to.
423423 read_pos : usize = 0 ,
424424
425+ // Depending on which version of TLS, there are different places during
426+ // the handshake that we want to start receiving from. We can't have
427+ // overlapping receives (works fine on MacOS (kqueue) but not Linux (
428+ // io_uring)). Using this boolean as a guard, to make sure we only have
429+ // 1 in-flight receive is easier than trying to understand TLS.
430+ is_receiving : bool = false ,
431+
425432 // need a separate read and write buf because, with TLS, messages are
426433 // not strictly req->resp.
427434 write_buf : []u8 ,
@@ -545,6 +552,10 @@ fn AsyncHandler(comptime H: type, comptime L: type) type {
545552 // while handshaking and potentially while sending data. So we're always
546553 // receiving.
547554 fn receive (self : * Self ) void {
555+ if (self .is_receiving ) {
556+ return ;
557+ }
558+ self .is_receiving = true ;
548559 return self .loop .recv (
549560 Self ,
550561 self ,
@@ -557,6 +568,7 @@ fn AsyncHandler(comptime H: type, comptime L: type) type {
557568
558569 fn received (self : * Self , _ : * IO.Completion , n_ : IO .RecvError ! usize ) void {
559570 self .loop .onRecv (n_ );
571+ self .is_receiving = false ;
560572 const n = n_ catch | err | {
561573 return self .handleError ("Read error" , err );
562574 };
@@ -2109,8 +2121,13 @@ const CaptureHandler = struct {
21092121 }
21102122
21112123 fn waitUntilDone (self : * CaptureHandler ) ! void {
2112- try self .loop .io .run_for_ns (std .time .ns_per_ms * 25 );
2113- try self .reset .timedWait (std .time .ns_per_s );
2124+ for (0.. 20) | _ | {
2125+ try self .loop .io .run_for_ns (std .time .ns_per_ms * 25 );
2126+ if (self .reset .isSet ()) {
2127+ return ;
2128+ }
2129+ }
2130+ return error .TimeoutWaitingForRequestToComplete ;
21142131 }
21152132};
21162133
0 commit comments