Handle timeout of transactions that take too long
This commit is contained in:
parent
f5304237b5
commit
d9d9388978
36
src/root.zig
36
src/root.zig
@ -31,6 +31,9 @@ pub const Root = struct {
|
|||||||
// A value of 0 means there is no current transaction.
|
// A value of 0 means there is no current transaction.
|
||||||
pending_count: u32,
|
pending_count: u32,
|
||||||
|
|
||||||
|
/// Handles timeout of transactions
|
||||||
|
transaction_timer: ?*c.wl_event_source,
|
||||||
|
|
||||||
pub fn init(self: *Self, server: *Server) !void {
|
pub fn init(self: *Self, server: *Server) !void {
|
||||||
self.server = server;
|
self.server = server;
|
||||||
|
|
||||||
@ -216,7 +219,27 @@ pub const Root = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: start a timer and handle timeout waiting for all clients to ack
|
if (self.pending_count > 0) {
|
||||||
|
// TODO: log failure to create timer and commit immediately
|
||||||
|
self.transaction_timer = c.wl_event_loop_add_timer(
|
||||||
|
self.server.wl_event_loop,
|
||||||
|
handle_timeout,
|
||||||
|
self,
|
||||||
|
);
|
||||||
|
// Set timeout to 200ms
|
||||||
|
if (c.wl_event_source_timer_update(self.transaction_timer, 200) == -1) {
|
||||||
|
// TODO: handle failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_timeout(data: ?*c_void) callconv(.C) c_int {
|
||||||
|
const root = @ptrCast(*Root, @alignCast(@alignOf(*Root), data));
|
||||||
|
|
||||||
|
// TODO: log warning
|
||||||
|
root.commitTransaction();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn notifyConfigured(self: *Self) void {
|
pub fn notifyConfigured(self: *Self) void {
|
||||||
@ -228,15 +251,20 @@ pub const Root = struct {
|
|||||||
|
|
||||||
/// Apply the pending state and drop stashed buffers. This means that
|
/// Apply the pending state and drop stashed buffers. This means that
|
||||||
/// the next frame drawn will be the post-transaction state of the
|
/// the next frame drawn will be the post-transaction state of the
|
||||||
/// layout. Must only be called after all clients have configured for
|
/// layout. Should only be called after all clients have configured for
|
||||||
/// the new layout.
|
/// the new layout. If called early imperfect frames may be drawn.
|
||||||
fn commitTransaction(self: *Self) void {
|
fn commitTransaction(self: *Self) void {
|
||||||
// TODO: apply damage properly
|
// TODO: apply damage properly
|
||||||
|
|
||||||
|
// Ensure this is set to 0 to avoid entering invalid state (e.g. if called due to timeout)
|
||||||
|
self.pending_count = 0;
|
||||||
|
|
||||||
var it = self.views.first;
|
var it = self.views.first;
|
||||||
while (it) |node| : (it = node.next) {
|
while (it) |node| : (it = node.next) {
|
||||||
const view = &node.data;
|
const view = &node.data;
|
||||||
|
|
||||||
// TODO: handle views that timed out
|
// Ensure that all pending state is cleared
|
||||||
|
view.pending_serial = null;
|
||||||
view.current_state = view.pending_state;
|
view.current_state = view.pending_state;
|
||||||
view.dropStashedBuffer();
|
view.dropStashedBuffer();
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ pub const Server = struct {
|
|||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
|
|
||||||
wl_display: *c.wl_display,
|
wl_display: *c.wl_display,
|
||||||
|
wl_event_loop: *c.wl_event_loop,
|
||||||
wlr_backend: *c.wlr_backend,
|
wlr_backend: *c.wlr_backend,
|
||||||
wlr_renderer: *c.wlr_renderer,
|
wlr_renderer: *c.wlr_renderer,
|
||||||
|
|
||||||
@ -30,11 +31,15 @@ pub const Server = struct {
|
|||||||
self.allocator = allocator;
|
self.allocator = allocator;
|
||||||
|
|
||||||
// The Wayland display is managed by libwayland. It handles accepting
|
// The Wayland display is managed by libwayland. It handles accepting
|
||||||
// clients from the Unix socket, manging Wayland globals, and so on.
|
// clients from the Unix socket, managing Wayland globals, and so on.
|
||||||
self.wl_display = c.wl_display_create() orelse
|
self.wl_display = c.wl_display_create() orelse
|
||||||
return error.CantCreateWlDisplay;
|
return error.CantCreateWlDisplay;
|
||||||
errdefer c.wl_display_destroy(self.wl_display);
|
errdefer c.wl_display_destroy(self.wl_display);
|
||||||
|
|
||||||
|
// Should never return null if the display was created successfully
|
||||||
|
self.wl_event_loop = c.wl_display_get_event_loop(self.wl_display) orelse
|
||||||
|
return error.CantGetEventLoop;
|
||||||
|
|
||||||
// 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
|
||||||
// a tty or wayland if WAYLAND_DISPLAY is set.
|
// a tty or wayland if WAYLAND_DISPLAY is set.
|
||||||
|
Loading…
Reference in New Issue
Block a user