font: SharedGridSet locks and is thread-safe

This commit is contained in:
Mitchell Hashimoto
2024-04-06 10:08:52 -07:00
parent a22ca8e4c1
commit 00f677fd51

View File

@ -5,9 +5,8 @@
//! This structure allows expensive font information such as //! This structure allows expensive font information such as
//! the font atlas, glyph cache, font faces, etc. to be shared. //! the font atlas, glyph cache, font faces, etc. to be shared.
//! //!
//! This structure itself is not thread-safe. It is expected that a single //! This structure is thread-safe when the operations are documented
//! main app thread handles initializing new values and dispensing them to //! as thread-safe.
//! the appropriate threads.
const SharedGridSet = @This(); const SharedGridSet = @This();
const std = @import("std"); const std = @import("std");
@ -44,6 +43,9 @@ font_lib: Library,
/// Font discovery mechanism. /// Font discovery mechanism.
font_discover: ?Discover = null, font_discover: ?Discover = null,
/// Lock to protect multi-threaded access to the map.
lock: std.Thread.Mutex = .{},
/// Initialize a new SharedGridSet. /// Initialize a new SharedGridSet.
pub fn init(alloc: Allocator) !SharedGridSet { pub fn init(alloc: Allocator) !SharedGridSet {
var font_lib = try Library.init(); var font_lib = try Library.init();
@ -74,7 +76,9 @@ pub fn deinit(self: *SharedGridSet) void {
} }
/// Returns the number of cached grids. /// Returns the number of cached grids.
pub fn count(self: *const SharedGridSet) usize { pub fn count(self: *SharedGridSet) usize {
self.lock.lock();
defer self.lock.unlock();
return self.map.count(); return self.map.count();
} }
@ -94,6 +98,9 @@ pub fn ref(
var key = try Key.init(self.alloc, config); var key = try Key.init(self.alloc, config);
errdefer key.deinit(); errdefer key.deinit();
self.lock.lock();
defer self.lock.unlock();
const gop = try self.map.getOrPut(self.alloc, key); const gop = try self.map.getOrPut(self.alloc, key);
if (gop.found_existing) { if (gop.found_existing) {
log.debug("found cached grid for font config", .{}); log.debug("found cached grid for font config", .{});
@ -273,6 +280,9 @@ fn collection(
/// Decrement the ref count for the given key. If the ref count is zero, /// Decrement the ref count for the given key. If the ref count is zero,
/// the grid will be deinitialized and removed from the map.j:w /// the grid will be deinitialized and removed from the map.j:w
pub fn deref(self: *SharedGridSet, key: Key) void { pub fn deref(self: *SharedGridSet, key: Key) void {
self.lock.lock();
defer self.lock.unlock();
const entry = self.map.getEntry(key) orelse return; const entry = self.map.getEntry(key) orelse return;
assert(entry.value_ptr.ref >= 1); assert(entry.value_ptr.ref >= 1);