Editor component destroyed before callback finished

Hi,

in some cases it can happen (for example if a plugin-window in cubase is marked as “always on the top”) that the VST-Plugin-Editor will be closed (VstWrapper::deleteEditor()) before a callback like mouseDown() is finished, and that will result in a crash.
Has anyone an idea how to avoid this?

How is the fact that it’s always-on-top relevent? Do you mean you’ve made a juce window that’s always on top, or is that an option in cubase?

I mean the cubase function (it can be activated with right mouse click under the title bar, preset menu) . If the main window focus is changed from cubase to another application, all windows that have the “cubase-always on the top flag” will disappear. This can happen if you use a pop-up menu inside the plugin, and click outside the window, or when another application catches the focus.
The important thing is that it seams that cubase uses a another thread to close the gui (via vst-sdk function), while the message thread is doing a mouse-down callback in the same gui-object. Maybe the VstWrapper should wait until a running callbacks are finished.

Ah, I see. That’s nasty… I guess that some of the juce event handling would need to have more checks about whether the component is still valid before sending the events. Where’s the crash?

In my case, the application stops in a mouseDown Callback, after processing a popup-menu (PopUpMenu.show()) trying to lock a CriticalSection which was deleted before (i suppose while processing the popup-menu message loop) but it would crash in any other case too, when accessing a member.
So, the deletion does not have to be from another thread, but it can.

[code] ntdll.dll!7c92b1fa()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c96d414()
ntdll.dll!7c97c5cf()
ntdll.dll!7c9703b0()
ntdll.dll!7c9704a8()
ntdll.dll!7c970484()
ntdll.dll!7c911046()

test_debug.dll!juce::CriticalSection::enter() Line 81 + 0xc bytes C++
test_debug.dll!juce::ScopedLock::ScopedLock(const juce::CriticalSection & lock={…}) Line 75 + 0x33 bytes C++
test_debug.dll!my_Envelope::setXmlString(juce::String s={…}) Line 330 + 0xf bytes C++
test_debug.dll!my_EnvelopeBox::setXmlString(juce::String s={…}) Line 58 + 0x23 bytes C++
test_debug.dll!my_EnvelopeBox::mouseDown(const juce::MouseEvent & e={…}) Line 389 C++
test_debug.dll!juce::Component::internalMouseDown(const int x=211, const int y=56) Line 2558 + 0x16 bytes C++
test_debug.dll!juce::ComponentPeer::handleMouseDown(int x=211, int y=56, const int64 time=1221827097483) Line 250 C++
test_debug.dll!juce::Win32ComponentPeer::doMouseDown(const int x=558, const int y=464, const unsigned int wParam=2) Line 1404 C++
test_debug.dll!juce::Win32ComponentPeer::peerWindowProc(HWND
* h=0x00071080, unsigned int message=516, unsigned int wParam=2, long lParam=30409262) Line 1896 C++
test_debug.dll!juce::Win32ComponentPeer::windowProc(HWND__ * h=0x00071080, unsigned int message=516, unsigned int wParam=2, long lParam=30409262) Line 1841 + 0x18 bytes C++
[/code]

Oh, that’s particularly nasty, because once the comp has been deleted, control will return to the place after you called the modal function, and at that point you’ll have a whole stack full of deleted components. I think the only fix would be to defer deleting the plugin’s editor component if there’s currently a modal component active, but to send a message that will delete it at a later time.

Ok, try the version that I’ve just checked-in - it’s completely untested, but might work!

thanks but it doesn’t help, it seems that Component::getCurrentlyModalComponent() doesn’t recognize the popup-menu, even if i remove PopupMenu::dismissAllActiveMenus(); and put it behind the function.
I made some DBG-statements before and after popUpMenu.show() and i found out that the the host calls effEditClose, just after the popMenu is disappeared and before popUpMenu.show() exists.

this is the order:

Enter EnvelopeBox::mouseDown
PopMenu Start
modalComponentStack.size=0
Enter Modal State
modalComponentStack.size=1
modalComponentStack.size=2 (opening PopUp Sub menu)
modalComponentStack.size=1

Host Calls effEditClose and modalComponentStack.size=0
Delete Editor
PopMenu.show() returns
–> Crash

But with my changes, the deleteeditor call shouldn’t actually delete the editor yet, that should only happen later on, using a timer. Are you sure you correctly applied the change?

yes i’m sure. The problem is that Component::getCurrentlyModalComponent() returns zero and the editor will not be closed later.
If i modify the code that the Gui always will be closed later, this will also cause problems, an empty plugin-window will be shown.

Then I’m stumped - I don’t see how the current modal comp can be 0, if you move the dismissAllActiveMenus() call to be after checking for it…

Hi Jules, my assumption is, after or while the PopupMenuWindow will be closed, just exactly in the same moment/position, there must be a call to the OS (which closes the popup-window), which might changes the main window focus, and causes cubase to close the plugin-window.

So the juce internal modalComponentStack is empty, but the window which contains the popUpMenu will be closed a little little moment later, and at this moment the callback isn’t finished.

The issue doesn’t happens every time, but ca. every third try.

Well, if it’s using win32 calls to delete the window, then I guess there’s not much you can do about that…