@@ -23,14 +23,15 @@ const Completion = public.IO.Completion;
2323const AcceptError = public .IO .AcceptError ;
2424const RecvError = public .IO .RecvError ;
2525const SendError = public .IO .SendError ;
26+ const CloseError = public .IO .CloseError ;
2627const TimeoutError = public .IO .TimeoutError ;
2728
2829const MsgBuffer = @import ("msg.zig" ).MsgBuffer ;
2930const Browser = @import ("browser/browser.zig" ).Browser ;
3031const cdp = @import ("cdp/cdp.zig" );
3132
3233const NoError = error {NoError };
33- const IOError = AcceptError || RecvError || SendError || TimeoutError ;
34+ const IOError = AcceptError || RecvError || SendError || CloseError || TimeoutError ;
3435const Error = IOError || std .fmt .ParseIntError || cdp .Error || NoError ;
3536
3637// I/O Recv
@@ -47,6 +48,9 @@ pub const Cmd = struct {
4748 buf : []u8 , // only for read operations
4849 err : ? Error = null ,
4950
51+ completion : * Completion ,
52+ acceptCtx : * Accept = undefined ,
53+
5054 msg_buf : * MsgBuffer ,
5155
5256 // CDP
@@ -83,7 +87,9 @@ pub const Cmd = struct {
8387
8488 // read and execute input
8589 self .msg_buf .read (self .alloc (), input , self , Cmd .do ) catch | err | {
86- std .log .err ("do error: {any}" , .{err });
90+ if (err != error .Closed ) {
91+ std .log .err ("do error: {any}" , .{err });
92+ }
8793 return ;
8894 };
8995
@@ -101,8 +107,20 @@ pub const Cmd = struct {
101107 return self .browser .currentSession ().env ;
102108 }
103109
110+ // actions
111+ // -------
112+
104113 fn do (self : * Cmd , cmd : []const u8 ) anyerror ! void {
114+
115+ // close cmd
116+ if (std .mem .eql (u8 , cmd , "close" )) {
117+ self .loop .io .close (* Cmd , self , Cmd .closeCbk , self .completion , self .socket );
118+ return error .Closed ;
119+ }
120+
121+ // cdp cmd
105122 const res = cdp .do (self .alloc (), cmd , self ) catch | err | {
123+ // cdp end
106124 if (err == error .DisposeBrowserContext ) {
107125 try self .newSession ();
108126 return ;
@@ -124,6 +142,17 @@ pub const Cmd = struct {
124142 try self .browser .currentSession ().setInspector (cmd_opaque , Cmd .onInspectorResp , Cmd .onInspectorNotif );
125143 }
126144
145+ fn closeCbk (self : * Cmd , completion : * Completion , result : CloseError ! void ) void {
146+ _ = result catch | err | {
147+ self .err = err ;
148+ return ;
149+ };
150+ std .log .debug ("conn closed" , .{});
151+
152+ // continue accepting incoming requests
153+ self .loop .io .accept (* Accept , self .acceptCtx , Accept .cbk , completion , self .acceptCtx .socket );
154+ }
155+
127156 // Inspector
128157
129158 pub fn sendInspector (self : * Cmd , msg : []const u8 ) void {
@@ -264,12 +293,14 @@ pub fn listen(browser: *Browser, loop: *public.Loop, socket: std.posix.socket_t)
264293 // create I/O contexts and callbacks
265294 // for accepting connections and receving messages
266295 var ctxInput : [BufReadSize ]u8 = undefined ;
296+ var completion : Completion = undefined ;
267297 var cmd = Cmd {
268298 .loop = loop ,
269299 .browser = browser ,
270300 .socket = undefined ,
271301 .buf = & ctxInput ,
272302 .msg_buf = & msg_buf ,
303+ .completion = & completion ,
273304 };
274305 const cmd_opaque = @as (* anyopaque , @ptrCast (& cmd ));
275306 try browser .currentSession ().setInspector (cmd_opaque , Cmd .onInspectorResp , Cmd .onInspectorNotif );
@@ -278,9 +309,9 @@ pub fn listen(browser: *Browser, loop: *public.Loop, socket: std.posix.socket_t)
278309 .cmd = & cmd ,
279310 .socket = socket ,
280311 };
312+ cmd .acceptCtx = & accept ;
281313
282314 // accepting connection asynchronously on internal server
283- var completion : Completion = undefined ;
284315 loop .io .accept (* Accept , & accept , Accept .cbk , & completion , socket );
285316
286317 // infinite loop on I/O events, either:
0 commit comments