fix GUI VSTi khi PLAY: defer OPEN_GUI + silence same-path truoc attach (G0.1)

This commit is contained in:
2026-08-15 18:44:02 +07:00
parent 2890856d70
commit 18394807a9
2 changed files with 37 additions and 1 deletions
Binary file not shown.
+37 -1
View File
@@ -956,6 +956,19 @@ int main(int argc, char* argv[]) {
return;
}
}
// G0.1 (BUG_REPORT): mo GUI khi dang PLAY -> attachView chay tren worker
// thread trong luc audio loop process() cung DLL (2 thread 1 plugin) ->
// Nexus throw (createView/attached) -> GUI khong load + retry spam ->
// stall 3s -> watchdog kill bridge -> mat het instrument -> cam. Defer
// OPEN_GUI toi khi transport STOP (sweep duoi fulfill khi loaded &&
// transportStopped). Khong doi: tranh mat am; user STOP la GUI tu mo.
if (!transportStopped) {
std::cerr << "[NativeBridge] GUI deferred ch=" << guiCh
<< " plugin=" << pluginId << " (transport PLAY) - queued" << std::endl;
std::lock_guard<std::mutex> lock(g_pendingGuiMutex);
g_pendingGui[guiCh] = { (void*)arg1, pluginId };
return;
}
if (!workers[guiCh]) {
workers[guiCh] = std::make_unique<ChannelWorker>();
}
@@ -994,6 +1007,28 @@ int main(int argc, char* argv[]) {
}
}
#endif
// G0.1b: silence same-path instances on the MAIN thread BEFORE the
// attach job runs - renderAll of this loop iteration (and any before
// the worker sets reloading_) would otherwise process() another Nexus
// while the job's reload() (createInstance/terminate) enters the DLL
// -> 2 threads in 1 DLL -> Nexus hang -> writeIndex stall -> watchdog
// kills the bridge (observed: defer OK, attach after STOP still
// restarted). setReloading is a flag under the engine mutex; renderAll
// skips reloading channels, so no process() can race the job. The job
// keeps its own setReloading + restore logic unchanged. Dat o day (sau
// window create) de window fail khong keo mute vinh vien.
{
std::string gp0 = lower_plugin_path(guiCh);
if (!gp0.empty()) {
for (uint32_t y = 0; y < 16; ++y) {
if (y == guiCh) continue;
if (!instruments.get(y)) continue;
if (lower_plugin_path(y) == gp0)
instruments.setReloading(y, true);
}
instruments.setReloading(guiCh, true);
}
}
workers[guiCh]->post([&instruments, guiCh, hwnd, arg2 = pluginId]() {
if (!instruments.get(guiCh)) {
std::cerr << "[NativeBridge] GUI attach FAILED hwnd=" << hwnd
@@ -1424,7 +1459,8 @@ int main(int argc, char* argv[]) {
{
std::lock_guard<std::mutex> lock(g_pendingGuiMutex);
for (auto it = g_pendingGui.begin(); it != g_pendingGui.end(); ) {
if (instruments.get(it->first)) {
// G0.1: giu entry khi dang PLAY - handleOpenGui se defer lai
if (transportStopped && instruments.get(it->first)) {
readyGui.push_back({ it->first, it->second });
it = g_pendingGui.erase(it);
} else ++it;