aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2020-03-28 21:05:56 +0100
committerIsaac Freund <ifreund@ifreund.xyz>2020-03-28 21:05:56 +0100
commit029e49e1c54b836b54a1a7d1c51b6428864f2b2e (patch)
tree31aecd75152ddfa215fb3f206f2ce4799827e3a2 /src
parentd34df295f75248160c5116b1e94e1abd152d6878 (diff)
downloadriver-029e49e1c54b836b54a1a7d1c51b6428864f2b2e.tar.gz
river-029e49e1c54b836b54a1a7d1c51b6428864f2b2e.tar.xz
Gracefully handle transaction preemption
Diffstat (limited to 'src')
-rw-r--r--src/root.zig15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/root.zig b/src/root.zig
index b6f928e..cb5bae6 100644
--- a/src/root.zig
+++ b/src/root.zig
@@ -188,11 +188,17 @@ pub const Root = struct {
/// Initiate an atomic change to the layout. This change will not be
/// applied until all affected clients ack a configure and commit a buffer.
fn startTransaction(self: *Self) void {
- std.debug.assert(self.pending_count == 0);
+ // If a new transaction is started while another is in progress, we need
+ // to reset the pending count to 0 and clear serials from the views
+ self.pending_count = 0;
var it = self.views.first;
while (it) |node| : (it = node.next) {
const view = &node.data;
+
+ // Clear the serial in case this transaction is interrupting a prior one.
+ view.pending_serial = null;
+
if (view.needsConfigure()) {
view.configurePending();
self.pending_count += 1;
@@ -202,7 +208,12 @@ pub const Root = struct {
// redrawing.
view.sendFrameDone();
}
- view.stashBuffer();
+
+ // If there is a saved buffer present, then this transaction is interrupting
+ // a previous transaction and we should keep the old buffer.
+ if (view.stashed_buffer == null) {
+ view.stashBuffer();
+ }
}
// TODO: start a timer and handle timeout waiting for all clients to ack