aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2020-08-01 17:27:49 +0200
committerIsaac Freund <ifreund@ifreund.xyz>2020-08-01 17:27:49 +0200
commit56df9176b34c395b6ed7ed335a5ffe4a927eb88d (patch)
tree5e97ebe3f9f259c2c0bafc3703b565dd99cb349f
parent54b09c4ae949aebc986f724abab912e5cab0cc1e (diff)
downloadriver-56df9176b34c395b6ed7ed335a5ffe4a927eb88d.tar.gz
river-56df9176b34c395b6ed7ed335a5ffe4a927eb88d.tar.xz
server: handle SIGINT/SIGTERM with wl_event_loop
This is cleaner than having a separate signal handler and should be more consistent/reliable.
-rw-r--r--river/Root.zig2
-rw-r--r--river/Server.zig22
-rw-r--r--river/main.zig19
3 files changed, 22 insertions, 21 deletions
diff --git a/river/Root.zig b/river/Root.zig
index 95ab9db..c286c90 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -69,7 +69,7 @@ pub fn init(self: *Self, server: *Server) !void {
self.pending_configures = 0;
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,
self,
) orelse return error.AddTimerError;
diff --git a/river/Server.zig b/river/Server.zig
index 66af1e7..e06e1c6 100644
--- a/river/Server.zig
+++ b/river/Server.zig
@@ -37,7 +37,9 @@ const ViewStack = @import("view_stack.zig").ViewStack;
const XwaylandUnmanaged = @import("XwaylandUnmanaged.zig");
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,
noop_backend: *c.wlr_backend,
@@ -66,7 +68,13 @@ pub fn init(self: *Self) !void {
errdefer c.wl_display_destroy(self.wl_display);
// 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 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
pub fn deinit(self: *Self) void {
// 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);
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);
}
+/// 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 {
const self = @fieldParentPtr(Self, "listen_new_output", listener.?);
const wlr_output = util.voidCast(c.wlr_output, data.?);
diff --git a/river/main.zig b/river/main.zig
index 0de1856..7e47ec4 100644
--- a/river/main.zig
+++ b/river/main.zig
@@ -32,8 +32,6 @@ const usage: []const u8 =
\\
;
-var server: Server = undefined;
-
pub fn main() anyerror!void {
var startup_command: ?[*:0]const u8 = null;
{
@@ -71,15 +69,7 @@ pub fn main() anyerror!void {
log.info(.server, "initializing", .{});
- // Setup a handler for SIGINT and SIGTERM so we can clean up properly
- 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);
-
+ var server: Server = undefined;
try server.init();
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);
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,
- }
-}