Best way to tell if DAW spawns plugins in separate processes

An obvious solution would be to store the PID in a global static and check if an existing PID matches the current PID.

Is there some form of config I can get from juce, for such info, in a simple concrete/robust manner

Static variables are only accessible from within the process they are created in, so while they can be used to share data between multiple instances of a plugin running inside the same process, they are not suitable to share information between processes.

Identifying how a host handles this could be quite hard. But why do you care about that, why does your plugin need to know that? Maybe there is are other solutions to a problem you are facing with plugins running in their own process?

2 Likes

Note that Shared memory could be used between processes. I’m not aware of an already done portable mechanism for your need. (You could make something as a kinda InterProcessLock).

I actually can imagine a use case for this… I’ve just recently been working on integrating the MTS-ESP midi tuning library with my latest project, and for it to work properly it requires that plugins are run in the same process.

So I could imagine a scenario where if you detect that your host is spawning plugins in different processes, you can display a warning message such as “hey, MTS-ESP won’t work bc of how your DAW is configured”.

But as far as achieving how to detect that… I’m not sure.

1 Like

@g-mon has a shared memory class in his Gin module, I’ve never used it thus far, so perhaps he can comment on its suitability here.

In a plugin I’m involved with we used an UUID in a SharedResourcePointer, and then IPC to check between instances that they have the same UUID. This has worked absolutely flawlessly for me to detect if instances are running in different processes, but we have occasional reports from Logic users that it’s erroneously reporting that there is a mismatch.

4 Likes

I’m using a library that isn’t thread-safe. So, if the plugins are running in the same process, then my plugins can break.

So, what’s the plan? If you do determine at runtime that the host has launched you in the same process as another instance of your plugin, what do you do then?

Can’t you just use the library in a thread-safe way? i.e do all the work on the main thread. Or if you really have to, create a thread shared across the instances?

2 Likes

First of all the majority of hosts out there runs plugins in the host process, so if that should be a requirement for your plugin to work at all, the number of supported hosts would be very little.

But: I’m not sure if you are mixing up the concepts of threads and processes, both are a way to achieve parallelism, but processes act at a higher level and one process can run multiple threads. Running each plugin in its own process does not necessarily mean that thread safety issues are solved, since plugins will always be run on at least two threads, the audio thread and the message thread, but in reality most hosts run even more threads, so it’s perfectly possible that e.g. parameter updates come in from a dedicated thread etc.

On the other hand, depending on where the library is called in your code, it might be perfectly safe to assume that certain calls will always come from a certain thread, so it can be safe to use a non-threadsafe library in that context. Or you can add some safety mechanisms like locks or async callbacks on the message thread to ensure thread safety.

If you tell us a bit more about that library and how you use it, we could give you some more specific advice

3 Likes

use a lock…

If there is a way to detect whether the host has launched your plugin in a separate process or not, that detectiom wouldn’t happen until after your plugin is loaded. So I think it’s likely that if this library, or your usage of it, requires special configuration to be thread-safe, then you should just always use that setup, just to be safe.

But honestly, my suggestion would probably be to use a better library that has actually been written in a suitable way for your use case.

which means they can be used for detecting how your plugin is running (‘in-process’ or in separate processes).

for example if you incremented a static atomic int each time your plugin loads, in-process plugins would observe that value increasing greater than one. whereas separate-process plugins would observe the value never increasing greater than one when multiple instances are used.

In addition, any plugin that detects the presence of another instance of itself already running in-process (static int > 0) could refuse to load, thereby preventing the plugin breaking.

This solution is portable.

3 Likes

Good point. I was referring to the original idea of storing the PID into a static variable and use that to compare if it has changed - which obviously does not help since each process would only see its own PID. But your solution @JeffMcClintock is indeed a simple yet reliable solution to detect if a plugin instance is the first/only instance in a process!

Still, I believe that all that won’t help @tobiq solving issues with a non-threadsafe third party lib in a convenient way. But as I said above, without further detailed context, it’s difficult to give any good advice.

You clearly still don’t understand. Storing the PID in a static allows you to detect if the plugin has been launched in the same process as another plugin. The data stored in the static itself is arbitrary - perhaps that confused you

I do this already. However, “using that setup” comes with a cost. Hence why I dont want to use it, if not necessary

I really don’t understand how you might use the PID to figure that out. But I may be overlooking something, so I’d really appreciate some more detailed explanation on how you would use the PID stored into a static to figure that out, given the fact that each process has its own version of the static variable that another process cannot access – taken explicit IPC communication aside?

Plugin 1:
Loads on process 0x12
Checks if LOADED has been set
Sees nothing set - and sets LOADED = true

Plugin 2:
Loads on process 0x13
Checks if LOADED has been set
Sees nothing set - and sets LOADED = true

Plugin 2:
Loads on process 0x12
Checks if LOADED has been set
Sees flag set - handles multiple plugins being spawned within the same process

No complex IPC is necessary.

In the scenario you’ve just described, in process 0x12 you’ve now got 1 instance of your plugin running “normally” and one running in a “special mode” – I’m guessing as an under-the-hood configuration not visible to the user.

And because you said this, I’m guessing that the two instances will have noticeably different performance.

I think you’re going to get a lot of users confused and frustrated when your plugin works fine with one instance per track, but slows down massively when you try to load 2 or 3 into one DAW track…

I had got this backwards -it would be harder to detect if plugins are running in different processes. What’s wrong about the method you’re using? I can’t imagine anything simpler.

I don’t really need to go into any further detail - the comments have gone off-topic. My question was about whether JUCE provided a robust way to detect the plugin-spawning strategy of a DAW - and apparently, it does not