1const std = @import("../std.zig"); 2const RwLock = std.event.RwLock; 3 4/// Thread-safe async/await RW lock that protects one piece of data. 5/// Functions which are waiting for the lock are suspended, and 6/// are resumed when the lock is released, in order. 7pub fn RwLocked(comptime T: type) type { 8 return struct { 9 lock: RwLock, 10 locked_data: T, 11 12 const Self = @This(); 13 14 pub const HeldReadLock = struct { 15 value: *const T, 16 held: RwLock.HeldRead, 17 18 pub fn release(self: HeldReadLock) void { 19 self.held.release(); 20 } 21 }; 22 23 pub const HeldWriteLock = struct { 24 value: *T, 25 held: RwLock.HeldWrite, 26 27 pub fn release(self: HeldWriteLock) void { 28 self.held.release(); 29 } 30 }; 31 32 pub fn init(data: T) Self { 33 return Self{ 34 .lock = RwLock.init(), 35 .locked_data = data, 36 }; 37 } 38 39 pub fn deinit(self: *Self) void { 40 self.lock.deinit(); 41 } 42 43 pub fn acquireRead(self: *Self) callconv(.Async) HeldReadLock { 44 return HeldReadLock{ 45 .held = self.lock.acquireRead(), 46 .value = &self.locked_data, 47 }; 48 } 49 50 pub fn acquireWrite(self: *Self) callconv(.Async) HeldWriteLock { 51 return HeldWriteLock{ 52 .held = self.lock.acquireWrite(), 53 .value = &self.locked_data, 54 }; 55 } 56 }; 57} 58