[LV2] worker thread question

hermann meyer brummer- at web.de
Sun Dec 30 08:39:45 PST 2012


Am 30.12.2012 17:24, schrieb David Robillard:
> On Sun, 2012-12-30 at 11:20 +0100, hermann meyer wrote:
>> Am 30.12.2012 09:16, schrieb Robin Gareus:
>>> On 12/30/2012 08:43 AM, hermann meyer wrote:
>>>> Thanks Robin, for your input, what is open now for me is that I
>>>> need to read the port values in the worker thread, and that I would
>>>> watch them "outside" from run(). From what I understand about
>>>> glib-threads there is no problem as long I only read the values
>>>> were my pointers point to (data).
>>> I'm not aware of the spec mandating specific behavior of port values for
>>> the host-side implementation of the worker thread. Dave?
>>>
>>> You can access the instance LV2_Handle in the worker thread and
>>> you can also use the user-data field to pass information along to it.
>>>
>>> Since you likely have a local copy of the port data anyway (to compare
>>> if value_changed()) it's safer to use that local copy from your
>>> instance. Opposed to the data pointed to by ports, you are in control
>>> of that variable.
>>
>> But those copy is set by use a other thread then run() to get the port
>> value.
>> In fact it is set by the worker thread at the end of schedule.
>> So the outstanding question is, why should it be un-save to  (only) read
>> the value my pointer points to, from a other thread then run() ?
> Here is a valid host implementation approach in pseudo-code:
>
> void run_plugin(Plugin plugin, float control_value, uint32_t nframes)
> {
>      plugin.connect_port(0,&control_value);
>      plugin.run(nframes);
> }
>
> When this function returns, control_value (which is on the stack), does
> not exist anymore and will be immediately overwritten in the next
> function call.  A plugin thread that accesses that port will then read
> garbage on the stack, not the control value.
>
> Similar things happen if the host decides to connect the port to
> something else before/after run, which is more common.
>
> connect_port() is a mistake.  Pretend port buffers are a parameter to
> run() because that is what they conceptually are, and literally should
> be.
>
> Breaking thread rules in the spec can cause problems by definition,
> because it violates assumptions in host implementations.  Of all the
> things that it is bad to do, this is probably the worst.  The problems
> you cause by doing that can be notoriously difficult to detect and fix.
> It *might* work fine 9 times then crash on the tenth - during your live
> performance.  Not exactly what you want from quality audio software.
> On behalf of every host author (and user) ever, please don't do that.
> Ever.
>
> -dr
Okay, have learn again a bit, hope I didn't forget it again to soon. :-)
I have remove all threading stuff now, move the value check back into 
run, take a copy of my port values and call schedule->work() from run() 
to process my non rt work with the copy-ed values.

here is the link to the current state:
  http://sourceforge.net/p/guitarix/git/ci/34a056c8838c36d384751d7c11c6fdc936e2e9a6/tree/trunk/src/LV2/gxamp.lv2/gxamp.cpp

let me know case you see any violation in it any more.

regards
hermann



More information about the Devel mailing list