mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-20 18:56:08 +03:00
font: preload deferred faces in SharedGrid to avoid data races
Fixes #1722 Previously, SharedGrid.getIndex would properly lock any access to search for and load the face metadata for a font face that contains a codepoint. However, that face may be "deferred" (metadata loaded but the actual face not loaded). Later, outside of the SharedGrid write lock, a deferred face may be initialized and cause a data race if two threads are doing this at the same time, sometimes loading to a crash. This commit fixes the issue by always preloading font indexes in getIndex because the usage of getIndex implies a very near term future use of getFace.
This commit is contained in:
@ -142,6 +142,11 @@ pub fn cellSize(self: *SharedGrid) renderer.CellSize {
|
||||
}
|
||||
|
||||
/// Get the font index for a given codepoint. This is cached.
|
||||
///
|
||||
/// This always forces loading any deferred fonts since we assume that if
|
||||
/// you're looking up an index that the caller plans to use the font. By
|
||||
/// loading the font in this function we can ensure thread-safety on the
|
||||
/// load without complicating future calls.
|
||||
pub fn getIndex(
|
||||
self: *SharedGrid,
|
||||
alloc: Allocator,
|
||||
@ -171,6 +176,18 @@ pub fn getIndex(
|
||||
// Load a value and cache it. This even caches negative matches.
|
||||
const value = self.resolver.getIndex(alloc, cp, style, p);
|
||||
gop.value_ptr.* = value;
|
||||
|
||||
if (value) |idx| preload: {
|
||||
// If the font is a sprite font then we don't need to preload
|
||||
// because getFace doesn't work with special fonts.
|
||||
if (idx.special() != null) break :preload;
|
||||
|
||||
// Load the face in case its deferred. If this fails then we would've
|
||||
// failed to load it in the future anyways so we want to undo all
|
||||
// the caching we did.
|
||||
_ = try self.resolver.collection.getFace(idx);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user