@@ -30,6 +30,9 @@ const Browser = @import("browser/browser.zig").Browser;
3030const build_config = @import ("build_config" );
3131const parser = @import ("browser/netsurf.zig" );
3232
33+ var _app : ? * App = null ;
34+ var _server : ? Server = null ;
35+
3336pub fn main () ! void {
3437 // allocator
3538 // - in Debug mode we use the General Purpose Allocator to detect memory leaks
@@ -51,6 +54,34 @@ pub fn main() !void {
5154 };
5255}
5356
57+ // Handle app shutdown gracefuly on signals.
58+ fn shutdown () void {
59+ const sigaction : std.posix.Sigaction = .{
60+ .handler = .{
61+ .handler = struct {
62+ pub fn handler (_ : c_int ) callconv (.c ) void {
63+ // Shutdown service gracefuly.
64+ if (_server ) | server | {
65+ server .deinit ();
66+ }
67+ if (_app ) | app | {
68+ app .deinit ();
69+ }
70+ std .posix .exit (0 );
71+ }
72+ }.handler ,
73+ },
74+ .mask = std .posix .empty_sigset ,
75+ .flags = 0 ,
76+ };
77+ // Exit the program on SIGINT signal. When running the browser in a Docker
78+ // container, sending a CTRL-C (SIGINT) signal is catched but doesn't exit
79+ // the program. Here we force exiting on SIGINT.
80+ std .posix .sigaction (std .posix .SIG .INT , & sigaction , null );
81+ std .posix .sigaction (std .posix .SIG .TERM , & sigaction , null );
82+ std .posix .sigaction (std .posix .SIG .QUIT , & sigaction , null );
83+ }
84+
5485fn run (alloc : Allocator ) ! void {
5586 var args_arena = std .heap .ArenaAllocator .init (alloc );
5687 defer args_arena .deinit ();
@@ -81,7 +112,8 @@ fn run(alloc: Allocator) !void {
81112 const platform = try Platform .init ();
82113 defer platform .deinit ();
83114
84- var app = try App .init (alloc , .{
115+ // _app is global to handle graceful shutdown.
116+ _app = try App .init (alloc , .{
85117 .run_mode = args .mode ,
86118 .platform = & platform ,
87119 .http_proxy = args .httpProxy (),
@@ -92,6 +124,7 @@ fn run(alloc: Allocator) !void {
92124 .http_max_host_open = args .httpMaxHostOpen (),
93125 .http_max_concurrent = args .httpMaxConcurrent (),
94126 });
127+ const app = _app .? ;
95128 defer app .deinit ();
96129 app .telemetry .record (.{ .run = {} });
97130
@@ -103,7 +136,9 @@ fn run(alloc: Allocator) !void {
103136 return args .printUsageAndExit (false );
104137 };
105138
106- var server = try Server .init (app , address );
139+ // _server is global to handle graceful shutdown.
140+ _server = try Server .init (app , address );
141+ const server = & _server .? ;
107142 defer server .deinit ();
108143
109144 server .run (address , opts .timeout ) catch | err | {
0 commit comments