fix: fix Bluetooth shutdown delay with no active connections
This commit is contained in:
@@ -12,4 +12,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define MONTAUK_BUILD_NUMBER 64
|
#define MONTAUK_BUILD_NUMBER 66
|
||||||
|
|||||||
@@ -143,6 +143,23 @@ bool run_stage(void (*fn)(), uint64_t timeout_ms) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// True only if there is Bluetooth work to do: an adapter is present and at
|
||||||
|
// least one device is connected. bt_info/bt_list are non-blocking table reads
|
||||||
|
// that return immediately when no adapter exists (e.g. under QEMU), so this
|
||||||
|
// gate is effectively free.
|
||||||
|
bool bluetooth_has_active_connection() {
|
||||||
|
Montauk::BtAdapterInfo adapter;
|
||||||
|
if (montauk::bt_info(&adapter) != 0 || !adapter.initialized) {
|
||||||
|
return false; // no adapter
|
||||||
|
}
|
||||||
|
Montauk::BtDevInfo devs[8];
|
||||||
|
int n = montauk::bt_list(devs, 8);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (devs[i].connected) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Stage bodies -- no captured state, so they double as bare thread entries.
|
// Stage bodies -- no captured state, so they double as bare thread entries.
|
||||||
void stage_disconnect_bluetooth() {
|
void stage_disconnect_bluetooth() {
|
||||||
Montauk::BtDevInfo devs[8];
|
Montauk::BtDevInfo devs[8];
|
||||||
@@ -165,12 +182,16 @@ void perform_graceful_shutdown(LoginState* ls, int action) {
|
|||||||
const char* heading = rebooting ? "Restarting" : "Shutting Down";
|
const char* heading = rebooting ? "Restarting" : "Shutting Down";
|
||||||
|
|
||||||
// ==== Stage 1: disconnect connected Bluetooth devices ====
|
// ==== Stage 1: disconnect connected Bluetooth devices ====
|
||||||
// Bounded so an unresponsive controller cannot block the (critical)
|
// Skip entirely when there is no adapter or nothing connected, so a typical
|
||||||
// filesystem flush that follows.
|
// shutdown (and every QEMU run) does not pay for an empty stage. When there
|
||||||
|
// is work, it is bounded so an unresponsive controller cannot block the
|
||||||
|
// (critical) filesystem flush that follows.
|
||||||
|
if (bluetooth_has_active_connection()) {
|
||||||
show_stage(ls, heading, "Disconnecting Bluetooth devices...");
|
show_stage(ls, heading, "Disconnecting Bluetooth devices...");
|
||||||
if (!run_stage(stage_disconnect_bluetooth, BT_STAGE_TIMEOUT_MS)) {
|
if (!run_stage(stage_disconnect_bluetooth, BT_STAGE_TIMEOUT_MS)) {
|
||||||
show_stage(ls, heading, "Bluetooth is unresponsive, continuing...");
|
show_stage(ls, heading, "Bluetooth is unresponsive, continuing...");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ==== Stage 2: flush writes and unmount filesystems ====
|
// ==== Stage 2: flush writes and unmount filesystems ====
|
||||||
show_stage(ls, heading, "Flushing file systems...");
|
show_stage(ls, heading, "Flushing file systems...");
|
||||||
|
|||||||
@@ -17,5 +17,6 @@ extern "C" void _start() {
|
|||||||
montauk::print((const char*)username);
|
montauk::print((const char*)username);
|
||||||
montauk::print("\n");
|
montauk::print("\n");
|
||||||
|
|
||||||
|
|
||||||
montauk::exit(0);
|
montauk::exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user