@@ -23,67 +23,42 @@ const Allocator = std.mem.Allocator;
2323const log = @import ("log.zig" );
2424const App = @import ("app.zig" ).App ;
2525const Server = @import ("server.zig" ).Server ;
26+ const SigHandler = @import ("sighandler.zig" ).SigHandler ;
2627const Browser = @import ("browser/browser.zig" ).Browser ;
2728const DumpStripMode = @import ("browser/dump.zig" ).Opts .StripMode ;
2829
2930const build_config = @import ("build_config" );
3031
31- var _app : ? * App = null ;
32- var _server : ? Server = null ;
33-
3432pub fn main () ! void {
3533 // allocator
3634 // - in Debug mode we use the General Purpose Allocator to detect memory leaks
3735 // - in Release mode we use the c allocator
38- var gpa : std .heap .DebugAllocator (.{}) = .init ;
39- const alloc = if (builtin .mode == .Debug ) gpa .allocator () else std .heap .c_allocator ;
36+ var gpa_instance : std .heap .DebugAllocator (.{}) = .init ;
37+ const gpa = if (builtin .mode == .Debug ) gpa_instance .allocator () else std .heap .c_allocator ;
4038
4139 defer if (builtin .mode == .Debug ) {
42- if (gpa .detectLeaks ()) std .posix .exit (1 );
40+ if (gpa_instance .detectLeaks ()) std .posix .exit (1 );
4341 };
4442
45- run (alloc ) catch | err | {
43+ var arena_instance = std .heap .ArenaAllocator .init (gpa );
44+ const arena = arena_instance .allocator ();
45+ defer arena_instance .deinit ();
46+
47+ var sighandler = SigHandler { .arena = arena };
48+ try sighandler .install ();
49+
50+ run (gpa , arena , & sighandler ) catch | err | {
4651 // If explicit filters were set, they won't be valid anymore because
47- // the args_arena is gone. We need to set it to something that's not
48- // invalid. (We should just move the args_arena up to main)
52+ // the arena is gone. We need to set it to something that's not
53+ // invalid. (We should just move the arena up to main)
4954 log .opts .filter_scopes = &.{};
5055 log .fatal (.app , "exit" , .{ .err = err });
5156 std .posix .exit (1 );
5257 };
5358}
5459
55- // Handle app shutdown gracefuly on signals.
56- fn shutdown () void {
57- const sigaction : std.posix.Sigaction = .{
58- .handler = .{
59- .handler = struct {
60- pub fn handler (_ : c_int ) callconv (.c ) void {
61- // Shutdown service gracefuly.
62- if (_server ) | server | {
63- server .deinit ();
64- }
65- if (_app ) | app | {
66- app .deinit ();
67- }
68- std .posix .exit (0 );
69- }
70- }.handler ,
71- },
72- .mask = std .posix .empty_sigset ,
73- .flags = 0 ,
74- };
75- // Exit the program on SIGINT signal. When running the browser in a Docker
76- // container, sending a CTRL-C (SIGINT) signal is catched but doesn't exit
77- // the program. Here we force exiting on SIGINT.
78- std .posix .sigaction (std .posix .SIG .INT , & sigaction , null );
79- std .posix .sigaction (std .posix .SIG .TERM , & sigaction , null );
80- std .posix .sigaction (std .posix .SIG .QUIT , & sigaction , null );
81- }
82-
83- fn run (alloc : Allocator ) ! void {
84- var args_arena = std .heap .ArenaAllocator .init (alloc );
85- defer args_arena .deinit ();
86- const args = try parseArgs (args_arena .allocator ());
60+ fn run (gpa : Allocator , arena : Allocator , sighandler : * SigHandler ) ! void {
61+ const args = try parseArgs (arena );
8762
8863 switch (args .mode ) {
8964 .help = > {
@@ -110,13 +85,13 @@ fn run(alloc: Allocator) !void {
11085 const user_agent = blk : {
11186 const USER_AGENT = "User-Agent: Lightpanda/1.0" ;
11287 if (args .userAgentSuffix ()) | suffix | {
113- break :blk try std .fmt .allocPrintSentinel (args_arena . allocator () , "{s} {s}" , .{ USER_AGENT , suffix }, 0 );
88+ break :blk try std .fmt .allocPrintSentinel (arena , "{s} {s}" , .{ USER_AGENT , suffix }, 0 );
11489 }
11590 break :blk USER_AGENT ;
11691 };
11792
11893 // _app is global to handle graceful shutdown.
119- _app = try App .init (alloc , .{
94+ var app = try App .init (gpa , .{
12095 .run_mode = args .mode ,
12196 .http_proxy = args .httpProxy (),
12297 .proxy_bearer_token = args .proxyBearerToken (),
@@ -127,8 +102,6 @@ fn run(alloc: Allocator) !void {
127102 .http_max_concurrent = args .httpMaxConcurrent (),
128103 .user_agent = user_agent ,
129104 });
130-
131- const app = _app .? ;
132105 defer app .deinit ();
133106 app .telemetry .record (.{ .run = {} });
134107
@@ -141,10 +114,11 @@ fn run(alloc: Allocator) !void {
141114 };
142115
143116 // _server is global to handle graceful shutdown.
144- _server = try Server .init (app , address );
145- const server = & _server .? ;
117+ var server = try Server .init (app , address );
146118 defer server .deinit ();
147119
120+ try sighandler .on (Server .stop , .{& server });
121+
148122 // max timeout of 1 week.
149123 const timeout = if (opts .timeout > 604_800 ) 604_800_000 else @as (i32 , opts .timeout ) * 1000 ;
150124 server .run (address , timeout ) catch | err | {
0 commit comments