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:
@@ -169,7 +169,7 @@ fn spawn_bridge(
|
||||
match app
|
||||
.shell()
|
||||
.command(&bridge_exe)
|
||||
.env("SF_SHM_NAME", shm::SHM_NAME)
|
||||
.env("SF_SHM_NAME", shm::shm_name())
|
||||
.env("SF_PARENT_PID", std::process::id().to_string())
|
||||
.env("SF_SAMPLE_RATE", sample_rate.to_string())
|
||||
.env("SF_BLOCK_SIZE", "256")
|
||||
@@ -342,7 +342,7 @@ pub fn run() {
|
||||
let shm_created = Shm::create();
|
||||
println!(
|
||||
"SharedMemory {}: {}",
|
||||
shm::SHM_NAME,
|
||||
shm::shm_name(),
|
||||
if shm_created.is_some() { "created" } else { "unavailable (non-windows or error)" }
|
||||
);
|
||||
app.manage(ShmState(Mutex::new(shm_created)));
|
||||
@@ -588,7 +588,7 @@ fn open_vst_gui(app: AppHandle, plugin_id: String, channel: u8) -> Result<(), St
|
||||
#[derive(serde::Serialize)]
|
||||
struct BridgeStatus {
|
||||
connected: bool,
|
||||
shm_name: &'static str,
|
||||
shm_name: String,
|
||||
write_index: u32,
|
||||
block_timestamp: u64,
|
||||
shm_size_bytes: usize,
|
||||
@@ -610,7 +610,7 @@ fn bridge_status(app: AppHandle) -> Result<BridgeStatus, String> {
|
||||
let status = match guard.as_ref() {
|
||||
Some(shm) => BridgeStatus {
|
||||
connected: true,
|
||||
shm_name: shm::SHM_NAME,
|
||||
shm_name: shm::shm_name(),
|
||||
write_index: shm.write_index(),
|
||||
block_timestamp: shm.block_timestamp(),
|
||||
shm_size_bytes: std::mem::size_of::<shm::SharedAudioBufferIPC>(),
|
||||
@@ -623,7 +623,7 @@ fn bridge_status(app: AppHandle) -> Result<BridgeStatus, String> {
|
||||
},
|
||||
None => BridgeStatus {
|
||||
connected: false,
|
||||
shm_name: shm::SHM_NAME,
|
||||
shm_name: shm::shm_name(),
|
||||
write_index: 0,
|
||||
block_timestamp: 0,
|
||||
shm_size_bytes: 0,
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user