fix GUI VSTi khi PLAY: defer OPEN_GUI + silence same-path truoc attach (G0.1)
This commit is contained in:
Binary file not shown.
@@ -956,6 +956,19 @@ int main(int argc, char* argv[]) {
|
|||||||
return;
|
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]) {
|
if (!workers[guiCh]) {
|
||||||
workers[guiCh] = std::make_unique<ChannelWorker>();
|
workers[guiCh] = std::make_unique<ChannelWorker>();
|
||||||
}
|
}
|
||||||
@@ -994,6 +1007,28 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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]() {
|
workers[guiCh]->post([&instruments, guiCh, hwnd, arg2 = pluginId]() {
|
||||||
if (!instruments.get(guiCh)) {
|
if (!instruments.get(guiCh)) {
|
||||||
std::cerr << "[NativeBridge] GUI attach FAILED hwnd=" << hwnd
|
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);
|
std::lock_guard<std::mutex> lock(g_pendingGuiMutex);
|
||||||
for (auto it = g_pendingGui.begin(); it != g_pendingGui.end(); ) {
|
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 });
|
readyGui.push_back({ it->first, it->second });
|
||||||
it = g_pendingGui.erase(it);
|
it = g_pendingGui.erase(it);
|
||||||
} else ++it;
|
} else ++it;
|
||||||
|
|||||||
Reference in New Issue
Block a user