server: handle SIGINT/SIGTERM with wl_event_loop
This is cleaner than having a separate signal handler and should be more consistent/reliable.
This commit is contained in:
parent
54b09c4ae9
commit
56df9176b3
@ -69,7 +69,7 @@ pub fn init(self: *Self, server: *Server) !void {
|
|||||||
self.pending_configures = 0;
|
self.pending_configures = 0;
|
||||||
|
|
||||||
self.transaction_timer = c.wl_event_loop_add_timer(
|
self.transaction_timer = c.wl_event_loop_add_timer(
|
||||||
self.server.wl_event_loop,
|
c.wl_display_get_event_loop(self.server.wl_display),
|
||||||
handleTimeout,
|
handleTimeout,
|
||||||
self,
|
self,
|
||||||
) orelse return error.AddTimerError;
|
) orelse return error.AddTimerError;
|
||||||
|
@ -37,7 +37,9 @@ const ViewStack = @import("view_stack.zig").ViewStack;
|
|||||||
const XwaylandUnmanaged = @import("XwaylandUnmanaged.zig");
|
const XwaylandUnmanaged = @import("XwaylandUnmanaged.zig");
|
||||||
|
|
||||||
wl_display: *c.wl_display,
|
wl_display: *c.wl_display,
|
||||||
wl_event_loop: *c.wl_event_loop,
|
|
||||||
|
sigint_source: *c.wl_event_source,
|
||||||
|
sigterm_source: *c.wl_event_source,
|
||||||
|
|
||||||
wlr_backend: *c.wlr_backend,
|
wlr_backend: *c.wlr_backend,
|
||||||
noop_backend: *c.wlr_backend,
|
noop_backend: *c.wlr_backend,
|
||||||
@ -66,7 +68,13 @@ pub fn init(self: *Self) !void {
|
|||||||
errdefer c.wl_display_destroy(self.wl_display);
|
errdefer c.wl_display_destroy(self.wl_display);
|
||||||
|
|
||||||
// Never returns null if the display was created successfully
|
// Never returns null if the display was created successfully
|
||||||
self.wl_event_loop = c.wl_display_get_event_loop(self.wl_display).?;
|
const wl_event_loop = c.wl_display_get_event_loop(self.wl_display);
|
||||||
|
self.sigint_source = c.wl_event_loop_add_signal(wl_event_loop, std.os.SIGINT, terminate, self.wl_display) orelse
|
||||||
|
return error.AddEventSourceFailed;
|
||||||
|
errdefer _ = c.wl_event_source_remove(self.sigint_source);
|
||||||
|
self.sigterm_source = c.wl_event_loop_add_signal(wl_event_loop, std.os.SIGTERM, terminate, self.wl_display) orelse
|
||||||
|
return error.AddEventSourceFailed;
|
||||||
|
errdefer _ = c.wl_event_source_remove(self.sigterm_source);
|
||||||
|
|
||||||
// The wlr_backend abstracts the input/output hardware. Autocreate chooses
|
// The wlr_backend abstracts the input/output hardware. Autocreate chooses
|
||||||
// the best option based on the environment, for example DRM when run from
|
// the best option based on the environment, for example DRM when run from
|
||||||
@ -129,6 +137,9 @@ pub fn init(self: *Self) !void {
|
|||||||
/// Free allocated memory and clean up
|
/// Free allocated memory and clean up
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
// Note: order is important here
|
// Note: order is important here
|
||||||
|
_ = c.wl_event_source_remove(self.sigint_source);
|
||||||
|
_ = c.wl_event_source_remove(self.sigterm_source);
|
||||||
|
|
||||||
if (build_options.xwayland) c.wlr_xwayland_destroy(self.wlr_xwayland);
|
if (build_options.xwayland) c.wlr_xwayland_destroy(self.wlr_xwayland);
|
||||||
|
|
||||||
c.wl_display_destroy_clients(self.wl_display);
|
c.wl_display_destroy_clients(self.wl_display);
|
||||||
@ -157,6 +168,13 @@ pub fn run(self: Self) void {
|
|||||||
c.wl_display_run(self.wl_display);
|
c.wl_display_run(self.wl_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle SIGINT and SIGTERM by gracefully stopping the server
|
||||||
|
fn terminate(signal: c_int, data: ?*c_void) callconv(.C) c_int {
|
||||||
|
const wl_display = util.voidCast(c.wl_display, data.?);
|
||||||
|
c.wl_display_terminate(wl_display);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fn handleNewOutput(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
|
fn handleNewOutput(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
|
||||||
const self = @fieldParentPtr(Self, "listen_new_output", listener.?);
|
const self = @fieldParentPtr(Self, "listen_new_output", listener.?);
|
||||||
const wlr_output = util.voidCast(c.wlr_output, data.?);
|
const wlr_output = util.voidCast(c.wlr_output, data.?);
|
||||||
|
@ -32,8 +32,6 @@ const usage: []const u8 =
|
|||||||
\\
|
\\
|
||||||
;
|
;
|
||||||
|
|
||||||
var server: Server = undefined;
|
|
||||||
|
|
||||||
pub fn main() anyerror!void {
|
pub fn main() anyerror!void {
|
||||||
var startup_command: ?[*:0]const u8 = null;
|
var startup_command: ?[*:0]const u8 = null;
|
||||||
{
|
{
|
||||||
@ -71,15 +69,7 @@ pub fn main() anyerror!void {
|
|||||||
|
|
||||||
log.info(.server, "initializing", .{});
|
log.info(.server, "initializing", .{});
|
||||||
|
|
||||||
// Setup a handler for SIGINT and SIGTERM so we can clean up properly
|
var server: Server = undefined;
|
||||||
var act = std.os.Sigaction{
|
|
||||||
.sigaction = handleSignal,
|
|
||||||
.mask = std.os.empty_sigset,
|
|
||||||
.flags = 0,
|
|
||||||
};
|
|
||||||
std.os.sigaction(std.os.SIGINT, &act, null);
|
|
||||||
std.os.sigaction(std.os.SIGTERM, &act, null);
|
|
||||||
|
|
||||||
try server.init();
|
try server.init();
|
||||||
defer server.deinit();
|
defer server.deinit();
|
||||||
|
|
||||||
@ -109,10 +99,3 @@ fn printErrorExit(comptime format: []const u8, args: var) noreturn {
|
|||||||
stderr.print(format ++ "\n", args) catch std.os.exit(1);
|
stderr.print(format ++ "\n", args) catch std.os.exit(1);
|
||||||
std.os.exit(1);
|
std.os.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleSignal(sig: i32, info: *const std.os.siginfo_t, ctx_ptr: ?*const c_void) callconv(.C) void {
|
|
||||||
switch (sig) {
|
|
||||||
std.os.SIGINT, std.os.SIGTERM => c.wl_display_terminate(server.wl_display),
|
|
||||||
else => unreachable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user