G3.1: dedicated bridge heartbeat — watchdog liveness independent of audio loop

This commit is contained in:
2026-08-16 10:04:16 +07:00
parent b59e416566
commit 30fa98a441
6 changed files with 186 additions and 31 deletions
+6
View File
@@ -55,4 +55,10 @@ struct SharedAudioBufferIPC {
// to extend its stall deadline — a long Nexus attach must not look like
// a dead bridge. Append-only field: existing offsets stay stable.
volatile uint32_t attachInFlight;
// G3.1: dedicated heartbeat, incremented every 100ms by a bridge-side
// thread INDEPENDENT of the audio loop. The Tauri watchdog keys bridge
// liveness on this, so a slow (but alive) audio loop no longer looks dead.
// Append-only field: existing offsets stay stable.
volatile uint32_t heartbeat;
};
+11
View File
@@ -657,6 +657,17 @@ int main(int argc, char* argv[]) {
if (!shmIPC) return 1;
#endif
// G3.1: dedicated heartbeat thread, independent of the audio loop.
// Increments every 100ms (~10Hz). Tauri watchdog keys liveness on this.
// Started right after the SHM map so a slow instrument restore at
// startup (or after watchdog respawn) never looks like a dead bridge.
std::thread([shmIPC]() {
for (;;) {
Sleep(100);
shmIPC->heartbeat++;
}
}).detach();
InstrumentEngineManager instruments;
#ifdef _WIN32
g_engine = &instruments;
+1
View File
@@ -65,6 +65,7 @@ int main() {
// 5. Layout stability — MUST match Rust src-tauri/src/shm.rs
assert(sizeof(SharedAudioBufferIPC::MidiEventIPC) == 12);
assert(sizeof(SharedAudioBufferIPC::ControlEventIPC) == 1040);
assert(sizeof(SharedAudioBufferIPC) == 11168); // G3.1: +4 heartbeat
std::printf("SHM self-check OK (sizeof struct = %zu bytes)\n", sizeof(SharedAudioBufferIPC));
shm_close(h);