Closed reuk closed 3 years ago
Very interesting...
I am not familiar with macOS internals, or the new pugl code for it, but if this works fine without calling puglUpdate then we can consider it for macOS builds. But a few precautions needed:
Window::addCallback()
(not to be confused with the Application method with the same name, the Window one provides a timeout arg)If those 3 cases still work, then we are safe.
Thanks for the info.
I am not familiar with macOS internals, or the new pugl code for it, but if this works fine without calling puglUpdate then we can consider it for macOS builds.
I'm not necessarily suggesting to avoid calling puglUpdate altogether, as I think this would break some of the other points you mentioned. The calls to puglDispatchSimpleEvent (..., PUGL_UPDATE)
and [view->impl->drawView displayIfNeeded]
look important (I haven't tried testing without them yet).
That being said, the sendEvent
part of that function seems quite dangerous, and I suspect it could be removed in plugins without any adverse effects.
Perhaps pugl needs to be aware of how it is being used, and disable the event processing code if it is not necessary, e.g. in a plugin. Alternatively, puglUpdate could be split into separate puglUpdateWithInternalEventLoop
and puglUpdateWithExternalEventLoop
functions, allowing users to pick the appropriate version to call depending on the context.
Having said that, this is starting to sound more like an issue with pugl, so I've opened an issue on that repo too.
This happens on Mac/Live/VST as well with puglUpdate
being the culprit. Removing the call avoids the crash without noticeable side effects but yes it is a cheap hack... Adding some more evidence:
Thread 0 Crashed:: MainThread Dispatch queue: com.apple.main-thread
0 net.sf.distrho.d_states 0x0000000120ef7628 puglUpdate + 904
1 net.sf.distrho.d_states 0x0000000120f006ac DGL::Application::PrivateData::idle(unsigned int) + 76
2 net.sf.distrho.d_states 0x0000000120efe620 DISTRHO::UIVst::idle() + 192
3 net.sf.distrho.d_states 0x0000000120efb3c7 DISTRHO::PluginVst::vst_dispatcher(int, int, long, void*, float) + 823
...
https://user-images.githubusercontent.com/930494/127978368-8c303b38-cda3-4c1f-8126-673fdbf67f0d.mov
I have merged @reuk 's fixes into DISTRHO/pugl repository and updated the DPF submodules. This should take care of the crashes, thanks a lot!
Testing is much appreciated.
Tried all DPF examples in both Live 10 and REAPER and the crashes are gone.
Closing this now, as I forgot to do it before
Environment
Steps to reproduce
As far as I can tell, puglUpdate calls sendEvent to process UI events. Occasionally it will process an event which closes the UI window and the LV2 UI instance. As the stack unwinds, it tries to use some freed resource, crashing the program.
I'm not sure whether this is a bug in DPF or pugl (or elsewhere?) but DPF seems like the most likely candidate. On platforms where the process has a single shared event loop (windows/mac) I don't think it should be necessary to process application events from within a plugin's UI. To test this theory, I tried commenting out the event-handling bit of puglUpdate and building the Parameters demo plugin. Loading the modified plugin in REAPER, the blue squares still turn orange in response to mouse clicks as you'd expect.
It seems reasonable that the idle callback should not be used to invoke any action that might cause the UI to be destroyed, but perhaps I'm missing some important context here.
I did consider that this might be a bug in REAPER rather than in the plugin, but fixing such a bug would require REAPER to be written in such a way that any event could come from inside an idle callback. This would make it impossible to immediately destroy any plugin UI in response to a user interaction or other event, which doesn't sound practical.