fix crash daw_vst_bridge khi đóng editor Nexus đang play: reload instance trong close job + silence same-plugin quanh createInstance/createView

This commit is contained in:
2026-08-14 16:52:53 +07:00
parent 0696545ae9
commit af59aaf257
5 changed files with 325 additions and 56 deletions
+13 -17
View File
@@ -246,12 +246,7 @@ bool Vst3Instrument::loadPlugin(const std::string& path, double sampleRate) {
std::cerr << "[dbg] loadPlugin: createInstance ..." << std::endl;
std::cerr << "[dbg] loadPlugin: chosen name=" << chosen.name() << " category=" << chosen.category()
<< " subcat=" << chosen.subCategoriesString() << " idbytes=";
{
const unsigned char* cid2 = (const unsigned char*)chosen.ID().data();
for (int b = 0; b < 16; ++b) std::cerr << std::hex << (int)cid2[b] << ' ';
std::cerr << std::dec << std::endl;
}
<< " subcat=" << chosen.subCategoriesString() << std::endl;
IPtr<IComponent> component = factory.createInstance<IComponent>(chosen.ID());
if (!component) {
std::cerr << "[Vst3Instrument] createInstance<IComponent> failed" << std::endl;
@@ -579,16 +574,6 @@ bool Vst3Instrument::attachView(void* parentWindowHandle) {
if (!s || !s->controller || !parentWindowHandle) return false;
IPlugView* rawView = nullptr;
tresult qi = s->controller->queryInterface(IPlugView::iid, (void**)&rawView);
{
const unsigned char* iidb = (const unsigned char*)&IPlugView::iid;
std::cerr << "[dbg] openGUI: IPlugView::iid bytes=";
for (int b = 0; b < 16; ++b) std::cerr << std::hex << (int)iidb[b] << ' ';
std::cerr << std::dec << std::endl;
const unsigned char* eidb = (const unsigned char*)&IEditController::iid;
std::cerr << "[dbg] openGUI: IEditController::iid bytes=";
for (int b = 0; b < 16; ++b) std::cerr << std::hex << (int)eidb[b] << ' ';
std::cerr << std::dec << std::endl;
}
std::cerr << "[dbg] openGUI: controller qi IPlugView=" << (int)qi << " raw=" << (void*)rawView << " isSingle=" << (s->controllerIsComponent ? 1 : 0) << std::endl;
FUnknownPtr<IPlugView> view(rawView);
if (!view) {
@@ -669,7 +654,18 @@ void Vst3Instrument::closeGUI() {
return;
#else
auto* s = static_cast<Vst3HostState*>(state_);
if (s && s->view && guiAttached_) s->view->removed();
// Do NOT call s->view->removed(): Nexus's removed() enters an internal
// modal wait for a message only this thread's message pump can dispatch
// — but this thread is inside removed(), so it deadlocks forever
// (observed: closeGUI job never returns; wdisp flood from the editor).
// Nulling the view and letting the next terminate() (reload / destructor)
// tear the editor windows down on this same thread is the deterministic
// path out. Callers (post_close_gui / load job) additionally destroy the
// editor's child windows right here on this thread so the plugin stops
// pumping; the leaked editor object is inert once its windows are gone.
if (s && s->view && guiAttached_)
std::cerr << "[dbg] closeGUI: skip view->removed() (Nexus deadlock) view="
<< (void*)s->view << std::endl;
if (s) s->view = nullptr;
guiAttached_ = false;
#endif