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