TODO: ui: better mutex lock

alex 1 year ago
parent 0260d47747
commit 1d8d869629
Signed by: x1ddos
GPG Key ID: FDEFB4A63CBD8460

@ -67,8 +67,12 @@ export fn nm_get_curr_tick() u32 {
export fn nm_check_idle_time(_: *lvgl.LvTimer) void { export fn nm_check_idle_time(_: *lvgl.LvTimer) void {
const standby_idle_ms = 60000; // 60sec const standby_idle_ms = 60000; // 60sec
const idle_ms = lvgl.idleTime(); const idle_ms = lvgl.idleTime();
if (idle_ms > standby_idle_ms and state != .alert) { if (idle_ms < standby_idle_ms) {
state = .standby; return;
}
switch (state) {
.alert, .standby => {},
.active => state = .standby,
} }
} }
@ -105,10 +109,8 @@ export fn nm_wifi_start_connect(ssid: [*:0]const u8, password: [*:0]const u8) vo
}; };
} }
/// callers must hold ui mutex for the whole duration.
fn updateNetworkStatus(report: comm.Message.NetworkReport) !void { fn updateNetworkStatus(report: comm.Message.NetworkReport) !void {
ui_mutex.lock();
defer ui_mutex.unlock();
var wifi_list: ?[:0]const u8 = null; var wifi_list: ?[:0]const u8 = null;
var wifi_list_ptr: ?[*:0]const u8 = null; var wifi_list_ptr: ?[*:0]const u8 = null;
if (report.wifi_scan_networks.len > 0) { if (report.wifi_scan_networks.len > 0) {
@ -171,26 +173,32 @@ fn commThreadLoop() void {
/// runs one cycle of the commThreadLoop: read messages from stdin and update /// runs one cycle of the commThreadLoop: read messages from stdin and update
/// the UI accordingly. /// the UI accordingly.
/// holds ui mutex for most of the duration.
fn commThreadLoopCycle() !void { fn commThreadLoopCycle() !void {
const msg = try comm.read(gpa, stdin); const msg = try comm.read(gpa, stdin);
defer comm.free(gpa, msg); defer comm.free(gpa, msg);
logger.debug("got msg: {s}", .{@tagName(msg)}); logger.debug("got msg: {s}", .{@tagName(msg)});
switch (msg) {
.ping => try comm.write(gpa, stdout, comm.Message.pong), ui_mutex.lock(); // guards state and all UI calls below
.network_report => |report| { defer ui_mutex.unlock();
updateNetworkStatus(report) catch |err| logger.err("updateNetworkStatus: {any}", .{err}); switch (state) {
}, .standby => switch (msg) {
.poweroff_progress => |report| { .ping => try comm.write(gpa, stdout, comm.Message.pong),
ui_mutex.lock(); else => logger.debug("ignoring: in standby", .{}),
defer ui_mutex.unlock();
ui.poweroff.updateStatus(report) catch |err| logger.err("poweroff.updateStatus: {any}", .{err});
}, },
.bitcoind_report => |rep| { .active, .alert => switch (msg) {
ui_mutex.lock(); .ping => try comm.write(gpa, stdout, comm.Message.pong),
defer ui_mutex.unlock(); .network_report => |report| {
ui.bitcoin.updateTabPanel(rep) catch |err| logger.err("bitcoin.updateTabPanel: {any}", .{err}); updateNetworkStatus(report) catch |err| logger.err("updateNetworkStatus: {any}", .{err});
},
.poweroff_progress => |report| {
ui.poweroff.updateStatus(report) catch |err| logger.err("poweroff.updateStatus: {any}", .{err});
},
.bitcoind_report => |rep| {
ui.bitcoin.updateTabPanel(rep) catch |err| logger.err("bitcoin.updateTabPanel: {any}", .{err});
},
else => logger.warn("unhandled msg tag {s}", .{@tagName(msg)}),
}, },
else => logger.warn("unhandled msg tag {s}", .{@tagName(msg)}),
} }
} }
@ -212,7 +220,8 @@ fn uiThreadLoop() void {
comm.write(gpa, stdout, comm.Message.standby) catch |err| { comm.write(gpa, stdout, comm.Message.standby) catch |err| {
logger.err("comm.write standby: {any}", .{err}); logger.err("comm.write standby: {any}", .{err});
}; };
screen.sleep(&wakeup); // blocking // MUTEX???????????????????????????????????
screen.sleep(&ui_mutex, &wakeup); // blocking
// wake up due to touch screen activity or wakeup event is set // wake up due to touch screen activity or wakeup event is set
logger.info("waking up from sleep", .{}); logger.info("waking up from sleep", .{});

@ -13,12 +13,18 @@ const logger = std.log.scoped(.screen);
/// a touch screen activity or wake event is triggered. /// a touch screen activity or wake event is triggered.
/// sleep removes all input devices at enter and reinstates them at exit so that /// sleep removes all input devices at enter and reinstates them at exit so that
/// a touch event triggers no accidental action. /// a touch event triggers no accidental action.
pub fn sleep(wake: *const Thread.ResetEvent) void { pub fn sleep(mu: *std.Thread.Mutex, wake: *const Thread.ResetEvent) void {
drv.deinitInput(); drv.deinitInput();
mu.lock();
widget.topdrop(.show); widget.topdrop(.show);
mu.unlock();
defer { defer {
drv.initInput() catch |err| logger.err("drv.initInput: {any}", .{err}); drv.initInput() catch |err| logger.err("drv.initInput: {any}", .{err});
mu.lock();
widget.topdrop(.remove); widget.topdrop(.remove);
mu.unlock();
} }
const watcher = drv.InputWatcher() catch |err| { const watcher = drv.InputWatcher() catch |err| {