Fix OOM handling to be thread-safe

This commit is contained in:
Yorhel 2024-07-17 11:48:06 +02:00
parent 6bb31a4653
commit e5508ba9b4
2 changed files with 20 additions and 8 deletions

View file

@ -429,6 +429,8 @@ fn readExcludeFile(path: [:0]const u8) !void {
}
pub fn main() void {
ui.main_thread = std.Thread.getCurrentId();
// Grab thousands_sep from the current C locale.
_ = c.setlocale(c.LC_ALL, "");
if (c.localeconv()) |locale| {
@ -574,6 +576,8 @@ var event_delay_timer: std.time.Timer = undefined;
// Draw the screen and handle the next input event.
// In non-blocking mode, screen drawing is rate-limited to keep this function fast.
pub fn handleEvent(block: bool, force_draw: bool) void {
while (ui.oom_threads.load(.monotonic) > 0) ui.oom();
if (block or force_draw or event_delay_timer.read() > config.update_delay) {
if (ui.inited) _ = ui.c.erase();
switch (state) {

View file

@ -18,6 +18,8 @@ pub const c = @cImport({
});
pub var inited: bool = false;
pub var main_thread: std.Thread.Id = undefined;
pub var oom_threads = std.atomic.Value(usize).init(0);
pub var rows: u32 = undefined;
pub var cols: u32 = undefined;
@ -43,15 +45,21 @@ pub fn quit() noreturn {
// Also, init() and other ncurses-related functions may have hidden allocation,
// no clue if ncurses will consistently report OOM, but we're not handling that
// right now.
// TODO: Make thread-safe!
pub fn oom() void {
const haveui = inited;
deinit();
const stderr = std.io.getStdErr();
stderr.writeAll("\x1b7\x1b[JOut of memory, trying again in 1 second. Hit Ctrl-C to abort.\x1b8") catch {};
std.time.sleep(std.time.ns_per_s);
if (haveui)
init();
@setCold(true);
if (main_thread == std.Thread.getCurrentId()) {
const haveui = inited;
deinit();
const stderr = std.io.getStdErr();
stderr.writeAll("\x1b7\x1b[JOut of memory, trying again in 1 second. Hit Ctrl-C to abort.\x1b8") catch {};
std.time.sleep(std.time.ns_per_s);
if (haveui)
init();
} else {
_ = oom_threads.fetchAdd(1, .monotonic);
std.time.sleep(std.time.ns_per_s);
_ = oom_threads.fetchSub(1, .monotonic);
}
}
// Dumb strerror() alternative for Zig file I/O, not complete.