updated logger: integrate mutex into WriterState (move-safety), fix lock/unlock logic in deinit
This commit is contained in:
@@ -55,20 +55,21 @@ pub const Logger = struct {
|
||||
level: Level = .info,
|
||||
on_error: ErrorCallback = null,
|
||||
|
||||
io: std.Io = undefined,
|
||||
state: *WriterState = undefined,
|
||||
mutex: std.Io.Mutex = undefined,
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
io: std.Io,
|
||||
state: *WriterState,
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
|
||||
const Self = @This();
|
||||
|
||||
/// Heap-allocated home for the write buffer and the `File.Writer`
|
||||
/// built on top of it. `File.Writer` holds a pointer into
|
||||
/// `buffer`, so both must live at a stable address that survives
|
||||
/// the `Logger` value itself being copied or moved.
|
||||
/// Heap-allocated home for the write buffer, the `File.Writer`
|
||||
/// built on top of it, and the mutex guarding both. `File.Writer`
|
||||
/// holds a pointer into `buffer`, so all three must live at a
|
||||
/// stable address that survives the `Logger` value itself being
|
||||
/// copied or moved.
|
||||
const WriterState = struct {
|
||||
buffer: []u8,
|
||||
mutex: std.Io.Mutex,
|
||||
writer: std.Io.File.Writer,
|
||||
};
|
||||
|
||||
@@ -92,15 +93,16 @@ pub const Logger = struct {
|
||||
const state = try allocator.create(WriterState);
|
||||
state.* = .{
|
||||
.buffer = buffer,
|
||||
.mutex = .init,
|
||||
.writer = options.file.writer(options.io, buffer),
|
||||
};
|
||||
|
||||
return Self{
|
||||
.level = options.level,
|
||||
.on_error = options.on_error,
|
||||
|
||||
.io = options.io,
|
||||
.state = state,
|
||||
.mutex = .init,
|
||||
.allocator = allocator,
|
||||
};
|
||||
}
|
||||
@@ -116,9 +118,12 @@ pub const Logger = struct {
|
||||
/// allocations are freed unconditionally.
|
||||
pub fn deinit(logger: *Self) void
|
||||
{
|
||||
logger.mutex.lock(logger.io) catch {};
|
||||
if (logger.state.mutex.lock(logger.io)) |_|
|
||||
{
|
||||
logger.state.writer.interface.flush() catch {};
|
||||
logger.mutex.unlock(logger.io);
|
||||
logger.state.mutex.unlock(logger.io);
|
||||
}
|
||||
else |_| {}
|
||||
|
||||
logger.allocator.free(logger.state.buffer);
|
||||
logger.allocator.destroy(logger.state);
|
||||
@@ -143,8 +148,8 @@ pub const Logger = struct {
|
||||
{
|
||||
if (@intFromEnum(level) < @intFromEnum(logger.level)) return;
|
||||
|
||||
try logger.mutex.lock(logger.io);
|
||||
defer logger.mutex.unlock(logger.io);
|
||||
try logger.state.mutex.lock(logger.io);
|
||||
defer logger.state.mutex.unlock(logger.io);
|
||||
|
||||
try logger.state.writer.interface.print(fmt, args);
|
||||
try logger.state.writer.interface.writeByte('\n');
|
||||
@@ -170,8 +175,8 @@ pub const Logger = struct {
|
||||
/// Returns an error if the underlying writer fails to flush.
|
||||
pub fn flush(logger: *Self) !void
|
||||
{
|
||||
try logger.mutex.lock(logger.io);
|
||||
defer logger.mutex.unlock(logger.io);
|
||||
try logger.state.mutex.lock(logger.io);
|
||||
defer logger.state.mutex.unlock(logger.io);
|
||||
|
||||
try logger.state.writer.interface.flush();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user