Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested event loop crash #56

Closed
reuk opened this issue Jul 26, 2021 · 5 comments
Closed

Nested event loop crash #56

reuk opened this issue Jul 26, 2021 · 5 comments
Labels

Comments

@reuk
Copy link
Contributor

reuk commented Jul 26, 2021

Potentially-linked issue in DPF: DISTRHO/DPF#299

It looks like when LV2 UIs call puglUpdate from the idle callback on macOS, they can occasionally process events which cause the UI to be destroyed. This in turn causes the host to crash, because the next part of puglUpdate tries to use resources which have been freed during sendEvent.

The issue linked above contains some steps to reproduce the issue.

I believe that it is an error to call NSApplication sendEvent from within a plugin. It places a very large burden on the host to assume that any event could be processed inside an LV2 idle callback. Hosts which weren't designed with LV2 in mind may have to undergo significant rewrites in order to work around this issue, if they can at all. It seems much more straightforward to provide both "standalone" and "plugin" versions of puglUpdate, so that users of pugl can avoid manually processing events in contexts which already have an event loop in place.

Would it be possible to modify pugl such that sendEvent can be bypassed in projects with an existing event loop?

@falkTX
Copy link
Contributor

falkTX commented Jul 26, 2021

pugl knows during runtime if the program is standalone or a plugin, so it can make a decision based on that.
A similar issue was pointed out in #55 where plugins are calling a global function typically reserved for hosts/standalones.

@drobilla
Copy link
Collaborator

The first part sounds like a bug that just needs to be fixed regardless, but I don't know about the second part. The sendEvent is there to "put back" events that pugl is not going to process because the event mask is not precise enough to filter out exactly the events that are handled specially.

The intent is not to "process" events there, just the opposite: sending the event to the application is the way pugl "puts back" the event, for lack of a proper way to do that (that I can find anyway). But MacOS is very unpredictable internally in general, IIRC nextEventMatchingMask itself dispatches events sometimes, and other system things do as well, more or less whenever. I am not sure this is possible to entirely avoid, even if pugl doesn't call sendEvent.

It's also not clear to me why this is problematic anyway. A more concrete example would help. But anyway, in short...

Would it be possible to modify pugl such that sendEvent can be bypassed in projects with an existing event loop?

I have no idea.

Maybe it's possible to specify just NSApplicationDefined as a mask to handle the client events, but this would only reduce the scope of the problem (though by quite a bit), or specify false for dequeue, but my experience with this method is that it's very cryptic and temperamental and usually doesn't do what you expect, so it will probably take some tinkering.

Have at it, but client events still need to work, so I don't think it's as simple as just stubbing the whole thing out.

@reuk
Copy link
Contributor Author

reuk commented Jul 30, 2021

I've pushed a potential fix to #57. It seems to work here, but it'd be great if you could try it out and check that I haven't missed any edge cases.

I'm not sure what you mean about a concrete example - DISTRHO/DPF#299 has an example of a real-world crash in REAPER caused by calling sendEvent from puglUpdate inside an LV2 UI's idle callback. It's reasonably easy to reproduce with the latest DPF demo projects.

@drobilla
Copy link
Collaborator

Returning to this one, I still don't quite get it. Obviously the quitting thing is an issue, but Pugl needs to dispatch events here somehow.

Maybe, at least in module mode, it should be working with the event queues of the views instead of the application? At a high level, that's what puglUpdate is supposed to do: update all the Pugl things, so if on MacOS sending events to the application makes them be processed immediately (which wasn't the intent there), then that shouldn't be happening?

Client events still need to work somehow though. I don't really understand how the event loop stuff works that well, but it doesn't seem to really fit the programming model to me. That said, MacOS in general doesn't fit it so well, so... whatever?

If it's really just the quit thing, I imagine that specific case can be suppressed, but I'm not enough of a MacOS expert to really know what the proper solution here is. Are there established vaguely similar projects (that set up and run sub-views on MacOS) that we can steal some inspiration from?

@drobilla drobilla added the bug label Nov 24, 2022
@drobilla
Copy link
Collaborator

Fixed in 28d75f7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants