termio: color change operations must gracefully handle renderer mailbox full (#9224)
Fixes #9191 This changes our color change operations from writing to the renderer mailbox directly to using our `rendererMailboxWriter` function which handles the scenario where the mailbox is full by yielding the lock, waking up the renderer, and retrying later. This is a known deadlock scenario we've worked around since the private beta days, but unfortunately this slipped through and I didn't catch it in review. What happens here is it's possible with certain escape sequences for the IO thread to saturate other mailboxes with messages while holding the terminal state lock. This can happen to any thread. This ultimately leads to starvation and all threads deadlock. Our IO thread is the only thread that produces this kind of massive stream of events while holding the lock, so we have helpers in it to attempt to queue (cheap, fast) and if that fails then to yield the lock, wakeup the target thread, requeue, and grab the lock again (expensive, slow).pull/9226/head
parent
3665040b59
commit
014a2e0042
|
|
@ -1192,21 +1192,21 @@ pub const StreamHandler = struct {
|
|||
.dynamic => |dynamic| switch (dynamic) {
|
||||
.foreground => {
|
||||
self.foreground_color = set.color;
|
||||
_ = self.renderer_mailbox.push(.{
|
||||
self.rendererMessageWriter(.{
|
||||
.foreground_color = set.color,
|
||||
}, .{ .forever = {} });
|
||||
});
|
||||
},
|
||||
.background => {
|
||||
self.background_color = set.color;
|
||||
_ = self.renderer_mailbox.push(.{
|
||||
self.rendererMessageWriter(.{
|
||||
.background_color = set.color,
|
||||
}, .{ .forever = {} });
|
||||
});
|
||||
},
|
||||
.cursor => {
|
||||
self.cursor_color = set.color;
|
||||
_ = self.renderer_mailbox.push(.{
|
||||
self.rendererMessageWriter(.{
|
||||
.cursor_color = set.color,
|
||||
}, .{ .forever = {} });
|
||||
});
|
||||
},
|
||||
.pointer_foreground,
|
||||
.pointer_background,
|
||||
|
|
@ -1246,9 +1246,9 @@ pub const StreamHandler = struct {
|
|||
.dynamic => |dynamic| switch (dynamic) {
|
||||
.foreground => {
|
||||
self.foreground_color = null;
|
||||
_ = self.renderer_mailbox.push(.{
|
||||
self.rendererMessageWriter(.{
|
||||
.foreground_color = self.foreground_color,
|
||||
}, .{ .forever = {} });
|
||||
});
|
||||
|
||||
self.surfaceMessageWriter(.{ .color_change = .{
|
||||
.target = target,
|
||||
|
|
@ -1257,9 +1257,9 @@ pub const StreamHandler = struct {
|
|||
},
|
||||
.background => {
|
||||
self.background_color = null;
|
||||
_ = self.renderer_mailbox.push(.{
|
||||
self.rendererMessageWriter(.{
|
||||
.background_color = self.background_color,
|
||||
}, .{ .forever = {} });
|
||||
});
|
||||
|
||||
self.surfaceMessageWriter(.{ .color_change = .{
|
||||
.target = target,
|
||||
|
|
@ -1269,9 +1269,9 @@ pub const StreamHandler = struct {
|
|||
.cursor => {
|
||||
self.cursor_color = null;
|
||||
|
||||
_ = self.renderer_mailbox.push(.{
|
||||
self.rendererMessageWriter(.{
|
||||
.cursor_color = self.cursor_color,
|
||||
}, .{ .forever = {} });
|
||||
});
|
||||
|
||||
if (self.default_cursor_color) |color| {
|
||||
self.surfaceMessageWriter(.{ .color_change = .{
|
||||
|
|
|
|||
Loading…
Reference in New Issue