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

Shared PluginLoadContext for multiple instances of the same plugin. #22

Merged

Conversation

Federerer
Copy link
Contributor

Looks like this change:

       I have now committed the change to make the load context not be shared across plugin instances.

Originally posted by @mikeoliphant in #2 (comment)

reintroduced an old bug related to wpf handles resources. This causes plugin to crash when using multiple instances, because of multiple versions of the assembly being loaded by the wpf framework.
dotnet/wpf#1700

This pr should fix this (at least for single plugin), the issue might still happen when using multiple plugins made with AudioPlugSharp, but it's less likely, because it would require them to share some library containing wpf controls.

@mikeoliphant
Copy link
Owner

I'm pretty sure I encountered issues with multiple plugins, but it has been a while and my memory is foggy.

As you point out, the underlying issue is with WPF. I've stopped using WPF for audio plugin work because of this, among other reasons. It seems unlikely that this WPF issue will be fixed.

As soon as I get a chance, I'll test this out - I'm happy to merge it if it at least makes things better in some cases.

@Federerer
Copy link
Contributor Author

I once tried to use Avalonia instead of WPF and it's doable, but also had some issues with multiple instances, as those frameworks aren't designed for such scenarios.

@mikeoliphant
Copy link
Owner

@Federerer Can you elaborate exactly what issue you are seeing with multiple instances, and how to reproduce it?

I just loaded up multiple instances of the LiveSPICE VST in Reaper and didn't see any issues.

@Federerer
Copy link
Contributor Author

This somehow always work when you add a new instance. Save your project, reopen it and then try to open the UI of all the instances (they'll process audio fine).

@mikeoliphant
Copy link
Owner

Yeah, I can reproduce that. It is very strange that it only seems to happen after a project re-load. It makes me wonder what is different in that situation, and whether there is another solution to the problem.

@mikeoliphant
Copy link
Owner

From messing around some more, I think it might have to do with whether the UI is opened before the next plugin is loaded. When you put new plugins on a track, that is the case. When you load a project, the last plugin gets it's UI loaded before any others.

Probably the issue is WPF only remembering the last context - and blowing up if it doesn't match.

Forcing instantiating of the UI at load time solves the problem. Not sure I want to do that, though.

Your solution should be fine as long as there are no other issues with sharing the load context per-plugin. So far I haven't seen any.

@mikeoliphant
Copy link
Owner

I just remembered another issue with the shared plugin load context - static variables get shared across plugin instances. While this could sometimes be handy, in general it will cause problems people wouldn't expect.

Ideally, this could be configured on a per-plugin basis. Unfortunately, you don't have access to a plugin until you've already loaded it in a load context... I guess plugin could first be loaded into a "quarantine" load context - but that would add extra overhead.

Maybe it would make sense to have the shared load context only be enabled in "AudioPlugSharpWPF".

@Federerer
Copy link
Contributor Author

I just remembered another issue with the shared plugin load context - static variables get shared across plugin instances.

I think this is also the case with native C++ plugins 🤔 That might or might not be a problem. It depends which UI framework you use. I need to check how Avalonia behaves in such case.

Unfortunately, you don't have access to a plugin until you've already loaded it in a load context...

I remember thinking about doing something like that - where Plugin class contains just metadata, and it's loaded from separate load context and only after that the processor is loaded from separate load context.

@mikeoliphant mikeoliphant merged commit d46214b into mikeoliphant:master Apr 23, 2023
@Federerer Federerer deleted the bug/location-based-plugin-loader branch May 6, 2023 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants