fix: bridge crash/stall when opening native VST GUI while playing

- Fix A (USER32 crash): WM_CLOSE no longer destroys the native VST
  window from the main thread (plugin editor children live on the
  channel worker thread). WM_CLOSE -> hide + closeGUI on worker;
  WM_DESTROY erases registry. LOAD_INSTRUMENT close uses closeGUI +
  SW_HIDE, waits on hasAttachedView() instead of registry erase.
- Fix B: per-process SHM name SonicForge_DAW_IPC_{pid} so stale
  bridges from old builds can never attach to a new app's ring buffer.
- Fix C (stall): opening editor for a plugin whose other channel still
  has a live instance of the same DLL (Nexus) deadlocked the audio
  loop (reload+createView on worker while audio thread processed the
  other instance). Silence same-path channels via setReloading during
  reload/attach, restore afterwards; audio resumes.
- Rebuild bridge + update install/ portable package.
This commit is contained in:
2026-08-14 14:36:34 +07:00
parent a1bbf549b7
commit 0696545ae9
6 changed files with 127 additions and 31 deletions
+9 -2
View File
@@ -12,7 +12,14 @@ use windows_sys::Win32::System::Memory::{
CreateFileMappingW, MapViewOfFile, UnmapViewOfFile, FILE_MAP_ALL_ACCESS, PAGE_READWRITE,
};
pub const SHM_NAME: &str = "SonicForge_DAW_IPC";
// SHM name RIENG cho tung process app: 2 instance (vi du bản portable install\
// + bản MSI cài song song) dung chung ten -> 2 bridge cung map 1 SHM -> ca 2
// drain control/midi queue (double instrument load, double GUI attach) -> race
// -> crash USER32 (Event Log 12:07:06 + 12:07:51: bridge MSI crash trong luc
// bridge portable dang chay). App PID duy nhat moi instance.
pub fn shm_name() -> String {
format!("SonicForge_DAW_IPC_{}", std::process::id())
}
pub const AUDIO_BLOCK_SIZE: usize = 256;
pub const MIDI_QUEUE_CAP: usize = 64;
pub const CONTROL_QUEUE_CAP: usize = 8;
@@ -67,7 +74,7 @@ impl Shm {
if !cfg!(windows) {
return None;
}
let name_wide: Vec<u16> = SHM_NAME.encode_utf16().chain(std::iter::once(0)).collect();
let name_wide: Vec<u16> = shm_name().encode_utf16().chain(std::iter::once(0)).collect();
let size = std::mem::size_of::<SharedAudioBufferIPC>() as u64;
let handle = unsafe {
CreateFileMappingW(