diff --git a/kernel/src/Api/BuildNo.hpp b/kernel/src/Api/BuildNo.hpp index 5b60b68..9deb047 100644 --- a/kernel/src/Api/BuildNo.hpp +++ b/kernel/src/Api/BuildNo.hpp @@ -12,4 +12,4 @@ #pragma once -#define MONTAUK_BUILD_NUMBER 64 +#define MONTAUK_BUILD_NUMBER 66 diff --git a/programs/src/login/login_shutdown.cpp b/programs/src/login/login_shutdown.cpp index dd1ed65..1332505 100644 --- a/programs/src/login/login_shutdown.cpp +++ b/programs/src/login/login_shutdown.cpp @@ -143,6 +143,23 @@ bool run_stage(void (*fn)(), uint64_t timeout_ms) { 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. void stage_disconnect_bluetooth() { Montauk::BtDevInfo devs[8]; @@ -165,11 +182,15 @@ void perform_graceful_shutdown(LoginState* ls, int action) { const char* heading = rebooting ? "Restarting" : "Shutting Down"; // ==== Stage 1: disconnect connected Bluetooth devices ==== - // Bounded so an unresponsive controller cannot block the (critical) - // filesystem flush that follows. - show_stage(ls, heading, "Disconnecting Bluetooth devices..."); - if (!run_stage(stage_disconnect_bluetooth, BT_STAGE_TIMEOUT_MS)) { - show_stage(ls, heading, "Bluetooth is unresponsive, continuing..."); + // Skip entirely when there is no adapter or nothing connected, so a typical + // 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..."); + if (!run_stage(stage_disconnect_bluetooth, BT_STAGE_TIMEOUT_MS)) { + show_stage(ls, heading, "Bluetooth is unresponsive, continuing..."); + } } // ==== Stage 2: flush writes and unmount filesystems ==== diff --git a/programs/src/whoami/main.cpp b/programs/src/whoami/main.cpp index cc2cf36..fb935cd 100644 --- a/programs/src/whoami/main.cpp +++ b/programs/src/whoami/main.cpp @@ -17,5 +17,6 @@ extern "C" void _start() { montauk::print((const char*)username); montauk::print("\n"); + montauk::exit(0); }