Calling setValueNotifyingHost() from processBlock()

I had a hard time with these kind of issues, some I could just settle but not resolve, when targeting FinalCut. e.g. here: Final Cut and the MessageThread
and some more…

I am super reluctant about too many asserts, I’d prefer educating developers using the documentation. In the linked case I was lucky, that removing the MessageManagerLock was an option.

Ah yes, I misunderstood your proposal, I figured you wanted to set the flag to “true” upon first processBlock to “tag” the thread from then on, which is something that I considered myself for exactly this purpose.

Regarding your idea, it is equivalent to having a method that informs whether the AudioProcessor::getCallbackLock() is taken by the current thread.

On one hand, that’s a facility that is already available for the special case of the MessageManagerLock, so I don’t see why not adding it also for the callback lock.

But on the other hand, I remember that when I suggested implementing something like that several years ago for CriticalSection, you dismissed the idea with valid arguments (can’t remember now), probably linked to the fact that one could write code that waited for the lock without actually locking, which seemed a bad idea.

EDIT: found it, 8 years have passed, maybe something has changed in the mean time:

FinalCut and WaveLab would probably be the two DAWs for which the isRealtimeFlagReliable() should return false, and hence all the assertions regarding isRealtimeThread() should take that into account, probably passing without being triggered.

What seems to be working as a solution to the original issue is the following;

In the processor class, I have a few doubles at class scope.

I derive from HighResolutionTimer, and I literally cut and pasted the automation code from the processBlock to the hiresTimerCallback().

I then added an if statement in processBlock() to control who sets the values of the doubles (either the process block, or the hiresTimerCallback()).

Now things work as before, but the automation operations are offloaded to another thread.

On Intel processors, this should be workable. On other processors, it will depend on how they deal with doubles.

I am still waiting for feedback from my user, but my testing is going well, so far.

Thanks to all for their help!

@jules, are there news about this?
I’m in a situation where it would be really nice to have the possibility to scatter around some assertions, to find where non-realtime-safe methods are being called from the realtime thread.

No, hadn’t got around to this yet. If you need a quick solution for adding your own asserts, it’s actually something you could easily do yourself in a couple of lines of code with a thread-local variable.

1 Like

There are some implementation complications though. I was trying to write something like that myself:

I added to AudioProcessor one such member:

 static ThreadLocalValue <bool> inProcessBlock;

But then I need to access it in the wrappers that call processBlock(), and therefore said member should be public, which doesn’t seem very safe to me. What do you think?

As a follow up on my original issue—my user who had an issue with Logic is now resolved. The fix I used (outlined above) did the trick. The work-around involved a HighResolutionTimer and its callback. The key being that the automation communication is handled on the timer thread.

In hindsight, it is a better way to do it. As usual, I learned something from this forum!

And, going forward, it would have been nice to have the asserts to warn of issues on the audio thread. That is a win for everybody.

Just seen this thread. Should it be ok to call these off a MIDI callback thread. Have the following scenario:

  1. In audiopluginhost, moving dials on the GUI correctly updates the parameter.
  2. In audiopluginhost, processing MIDI in correctly updates the parameter.
  3. In Live, moving dials on the GUI correctly updates the parameter
  4. In Live, processing MIDI in sporadically updates the parameter

Will moving the calls to setValueNotifyingHost() onto the message thread by one method or another fix this?


ok, i’ve knocked up a hacky solution to test and this is the case - these calls only work properly from the message thread - I guess these guard assertions were never put in place?