[LV2] worker thread question
brummer- at web.de
Fri Dec 28 09:50:42 PST 2012
Am 28.12.2012 17:38, schrieb David Robillard:
> On Fri, 2012-12-28 at 05:25 +0100, hermann meyer wrote:
>> . . but you will imagine that the design from the eg-sampler example
>> plugin is exactly were I'm talking about (and is what I'm tried first) .
>> The UI send a message to run() which in-turn fire up a worker thread.
>> The internal UI from the host didn't know about that and will not work.
>> So, the internal host UI is brocken.
> You seem confused. The UI, again, has nothing to do with the worker,
> everything about that is on the plugin side. The same message sent by a
> host UI would, of course, do the exact same thing, because... it's the
> same message.
Well, if the host didn't know the message, he cant send it.
> Also, it's unlikely a host would implement the worker by launching a
> thread for every request. There's just one worker thread. Possibly
> just one for many plugins, even.
> The UI of the eg-sampler is a silly thing because most host UIs
> currently don't understand how to send such messages. Hopefully that
> will change. Is this what you mean? That is unrelated to the worker
Exact, that is what I mean, for this case, a host UI cant work.
> There is nothing in the plugin interface about threads, there is no
> distinguishing between messages that will be processed in real-time and
> those that will not. This is probably a good thing.
>> Now I have some controllers which presented to the user as simple knobs,
>> like all other controllers as well, but those knobs control some
>> convolvers which need a impdata.update when the controller is moved.
>> Clearly that is a job for the worker-thread.
>> For the record,I have no problem to get it all work, that isn't what I'm
>> ask about, my question is related to the UI->host->engine communication,
>> which seems to me, break the internal host UI.
> Can you explain what you think is "broken" about host UIs?
Again, I have controllers which change a value, if the value change, a
worker thread is required. I could send a message from the plugin UI,
like eg-sampler do it, but then, the internal UI from the host didn't
work, simply because he didn't know that a message is to send. That is
simply a broken host UI for the plugin.
Alternatively I can check the value in run(), which is the rt-thread,
when I get it right :-) , and send the message from run, this way, the
host UI didn't need to know about a special message to send.
BUT, then I need to check the values from the controllers at any cycle
in run, that is, a wast of processing time. It isn't a big deal when I
have just one or two of those controllers which needs to be checked, but
again, they could become likely more, . . .
> As I said, you are confusing yourself by thinking about UIs. Make the
> plugin work. UIs just control plugins via ports. There is nothing
> special about changes that come from a UI or changes that come from
> anywhere else. This is deliberate, and a good thing.
>> A way to handle this issue is to watch the state of those convolver
>> controllers (in the engine) and fire a work thread when needed. This way
>> the internal UI from the host work as well.
> Sure. You can send send tasks to the worker from run() whenever you
> want for whatever reason.
>> Best way to handle this would be a watch thread (in the engine space)
>> were (controller) state changes could be fetched.
>> Imagine that it could come to plug-ins which need to watch a couple of
>> states, and it isn't nice by design to watch them in the rt-thread.
> Yes it is. Those changes, by definition, happen in the RT-thread. It
> would be an awful design to have a whole other thread just to watch for
> changes that arrive in run() anyway.
If I have a thread which run with a higher timeout, and in non rt, it
will spare a lot of processing time and it will keep the rt-thread clean
for plain dsp processing. :-)
> Sending messages to the worker is very cheap. The entire point of the
> extension is to queue non real-time work from run(). That is what you
> want to do, it is not a bad design, it is the intended and only purpose
> of the worker extension and it works well.
> The key thing to realize is that *all plugin I/O happens in run()*.
> The alternative is very, very unpleasant. Trust me, it existed before I
> designed the worker, and it's a total nightmare to have multiple
> contexts of I/O associated with different ports or APIs or whatever.
> This way, everything enters/leaves ports in run(), it's synchronous and
> simple, and if the plugin wants to queue off work to another thread, it
> is free to do so, but it doesn't complicate the interface of the plugin.
> It just works with ports and run() like every other LV2 plugin.
That is why I'm talking to you, before I implement my own watch thread,
i would talk to you about this need, as if you completely negate it, so
be it. Just think about, do you believe a plug-in like guitar-rig could
work without a own watch thread? Switch plugs in the plug on and off,
move there position in the processing chain?
That is exactly what I have in mind. The worker thread is a real good
extension to the LV2 specs, a additional watch thread would be awesome
and could extend the use of the worker thread to a bunch of possibility's.
> I think you are making this much more complicated than it needs to be.
> Your plugin interface is your plugin interface. Using the worker is
> purely an internal matter to the plugin.
More information about the Devel