Skip to content

Commit f15cf54

Browse files
committed
Fix deadlock on changing to builtin themes
1 parent 0afe1a0 commit f15cf54

1 file changed

Lines changed: 21 additions & 5 deletions

File tree

src/editor/OutputPanel.zig

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,29 @@ pub fn draw(_: ?*anyopaque) anyerror!void {
3232
var hbox = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .both });
3333
defer hbox.deinit();
3434

35-
OutputLog.lock();
36-
defer OutputLog.unlock();
37-
const lines = OutputLog.items();
35+
// Snapshot into the frame arena rather than holding `OutputLog`'s lock across the draw
36+
// below: that draw resolves the theme's mono font (see `mono` below), and some themes'
37+
// fonts fail to resolve, which logs a warning — reentering `OutputLog.append` on this
38+
// same thread. Holding the lock that long turns that into a self-deadlock (the log's
39+
// spinlock is not reentrant), so we copy what we need and unlock before drawing anything.
40+
const arena = dvui.currentWindow().arena();
41+
const lines: []const OutputLog.Line = blk: {
42+
OutputLog.lock();
43+
defer OutputLog.unlock();
44+
const src = OutputLog.items();
45+
const copy = arena.alloc(OutputLog.Line, src.len) catch break :blk &.{};
46+
for (src, copy) |s, *d| {
47+
d.* = .{
48+
.level = s.level,
49+
.scope = arena.dupe(u8, s.scope) catch "",
50+
.text = arena.dupe(u8, s.text) catch "",
51+
};
52+
}
53+
break :blk copy;
54+
};
3855

3956
// Distinct scopes seen so far, in first-seen order — small (one per active plugin), so a
40-
// linear scan per line is cheap. Arena-backed: pure per-frame scratch for the tab strip.
41-
const arena = dvui.currentWindow().arena();
57+
// linear scan per line is cheap.
4258
var scopes: std.ArrayListUnmanaged([]const u8) = .empty;
4359
for (lines) |line| {
4460
var seen = false;

0 commit comments

Comments
 (0)