diff --git a/src/Surface.zig b/src/Surface.zig index fc83e81f3..055f7c00c 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -872,10 +872,9 @@ fn queueIo( switch (msg) { .write_small, .write_stable, - => return, - - .write_alloc => |v| { - v.alloc.free(v.data); + .write_alloc, + => { + msg.deinit(); return; }, diff --git a/src/termio/Thread.zig b/src/termio/Thread.zig index 088096780..6b860a0d1 100644 --- a/src/termio/Thread.zig +++ b/src/termio/Thread.zig @@ -298,7 +298,7 @@ fn drainMailbox( // If we're draining, we just drain the mailbox and return. if (self.flags.drain) { - while (mailbox.pop(global.io())) |_| {} + while (mailbox.pop(global.io())) |msg| msg.deinit(); return; } diff --git a/src/termio/mailbox.zig b/src/termio/mailbox.zig index d5926f3a8..a053aaabe 100644 --- a/src/termio/mailbox.zig +++ b/src/termio/mailbox.zig @@ -47,6 +47,7 @@ pub const Mailbox = union(enum) { pub fn deinit(self: *Mailbox, alloc: Allocator) void { switch (self.*) { .spsc => |*v| { + while (v.queue.pop(global.io())) |msg| msg.deinit(); v.queue.destroy(alloc); v.wakeup.deinit(); }, @@ -76,6 +77,7 @@ pub const Mailbox = union(enum) { // lock so we need to unlock. mb.wakeup.notify() catch |err| { log.warn("failed to wake up writer, data will be dropped err={}", .{err}); + msg.deinit(); return; }; @@ -90,7 +92,7 @@ pub const Mailbox = union(enum) { // here. if (mutex) |m| m.unlock(global.io()); defer if (mutex) |m| m.lockUncancelable(global.io()); - _ = mb.queue.push(global.io(), msg, .{ .forever = {} }); + if (mb.queue.push(global.io(), msg, .{ .forever = {} }) == 0) msg.deinit(); }, } } diff --git a/src/termio/message.zig b/src/termio/message.zig index 63d34bb54..e51865e39 100644 --- a/src/termio/message.zig +++ b/src/termio/message.zig @@ -102,6 +102,19 @@ pub const Message = union(enum) { }; } + /// Free resources owned by a message that will not be processed. + /// The message is invalid after this call. + pub fn deinit(self: *const Message) void { + switch (self.*) { + .change_config => |v| { + v.ptr.deinit(); + v.alloc.destroy(v.ptr); + }, + .write_alloc => |v| v.alloc.free(v.data), + else => {}, + } + } + /// The types of size reports that we support. pub const SizeReport = terminal.size_report.Style; };