# Custom Listener and thread safety

**URL:** <https://forum.juce.com/t/custom-listener-and-thread-safety/38576>\
**Category:** General JUCE discussion\
**Created:** [April 9, 2020, 8:47am UTC](https://forum.juce.com/t/custom-listener-and-thread-safety/38576 "2020-04-09T08:47:21Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![domenicostefani](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/domenicostefani/32/8251_2.png) [@domenicostefani](https://forum.juce.com/u/domenicostefani)\
**Post date:** [April 9, 2020, 8:47am UTC](https://forum.juce.com/t/custom-listener-and-thread-safety/38576/1 "2020-04-09T08:47:21Z")

</div>

Hi, I’m a new entry in the JUCE world and audio programming in general and I encountered a problem in one of my first projects.  
I’m porting a rather simple onset detector, from another framework and I’m developing a demo application to understand interaction with JUCE.  
The AudioProcessor of my demo app owns a `OnsetDetector` object, initializes it an provides audio blocks that will be buffered and analysed.  
When the object detects the beginning of a note (onset) it has to communicate this event in an async fashion. For this I implemented a `OnsetDetector::Listener` class similarly to `Button::Listener` which contains a pure virtual callback function:

`virtual void onsetDetected (OnsetDetector *) = 0;`

OnsetDetector keeps a ListenerList (same as Button) and, when the onset is detected, it uses the `ListenerList::call` method:

`listeners.call([this] (Listener& l) { l.onsetDetected (this); });`

(Button uses callChecked instead, however I still have to understand what a BailoutChecker is, maybe I’m spinning too many plates at this point)

Now, for my demo the OnsetDetector Object is owned by the **AudioProcessor** and I would like to _change color of a Component in the **Editor** when the onset is detected_. I’ve read about AbstractFifo and updating regularly the Editor to pull parameter values from the Processor but it seems overkill for my purpose right now. It also seems inappropriate for an async event like this one.  
I tried using only the listener in 2 progressive steps:

- Implementing the `onsetDetected()` method and registering the listener in the **Processor** works fine but I obviously cannot access editor elements. Logging shows that it works.
- Leaving the `OnsetDetector` public in the **Processor** , implementing `onsetDetected()` in the **Editor** and registering the **Editor** as listener to the detector only works **partially** :

The callback method in the editor receives the call, it lights up a virual light bulb (change color of a Rectangle) for 100ms and than it switches it off (I call `repaint` twice: on turn on phase and turnoff). It works but it keeps violating an assertion in juce\_Component.cpp(r:1839):

`JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED`

Explained 2 lines before as: _If component methods are being called from threads other than the message thread, you’ll need to use a MessageManagerLock object to make sure it’s thread-safe._

1. Does this mean that the callback is called by the audio thread? (if so, this is unacceptable right?)
2. Is there a chance of making it work correctly (maybe with a MessageManagerLock) or am I going for a **bad paradigm** by using listeners like this?
3. Why does the “lightbulb” still work, even if the app is failing what seems like a crucial assertion?

I hope I haven’t bored you to death, this is as concise as I can get since the introduction to the environment feels like relevant context.  
I’m hoping that you can answer so this bit can be less of vodoo programming for me, thank you.

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [April 9, 2020, 9:10am UTC](https://forum.juce.com/t/custom-listener-and-thread-safety/38576/2 "2020-04-09T09:10:33Z")

</div>

1. Yes, the callback is being called on the audio thread currently, making the callback a bad place to update anything GUI related.
2. Updating the GUI directly from the audio thread won’t work. At a minimum, you’d have to take some kind of lock in the callback (possibly the MessageManagerLock) which would lead to priority inversion, possibly causing audio dropouts.
3. If you invoke undefined behaviour via data races in GUI components, stuff might appear to work perfectly, or it might immediately segfault or otherwise fail spectacularly. Whatever the observed behaviour of the program, it is still intrinsically broken (maybe it ran fine _this_ time, but might not next time).

You could take a look at the AudioProcessorValueTreeState attachment classes to see how they deal with getting parameter updates onto the GUI thread.

In this very simple case, you could also consider just sticking a `std::atomic<bool> thingIsActive;` member on your processor, updating it in your DSP callback, and then polling it using a `juce::Timer` to check whether you should redraw the ‘bulb’ component.

---

<div class="post-metadata">

**Author:** ![jellebakker](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jellebakker/32/17053_2.png) [@jellebakker](https://forum.juce.com/u/jellebakker)\
**Post date:** [April 9, 2020, 9:12am UTC](https://forum.juce.com/t/custom-listener-and-thread-safety/38576/3 "2020-04-09T09:12:41Z")

</div>

The goal is to visualise a short 100ms light on the GUI, right?  
I’d take this approach:

Add one atomic boolean, like @reuk suggests in the audioprocessor that is set to true in the audio thread when a note on arrives, the audio thread never sets it to false.

Then, a timer in the GUI thread reads the atomic bool at e.g. 30hz using atomic::exchange (false). If exchange return true, it means a note on arrived in the last 33 ms, the UI turns the light on, then after 100ms it should turn it off.

---

<div class="post-metadata">

**Author:** ![domenicostefani](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/domenicostefani/32/8251_2.png) [@domenicostefani](https://forum.juce.com/u/domenicostefani)\
**Post date:** [April 9, 2020, 9:33am UTC](https://forum.juce.com/t/custom-listener-and-thread-safety/38576/4 "2020-04-09T09:33:42Z")

</div>

Wow thanks to both of you for the quick and clear replies @reuk @jellebakker !  
The std::atomic fix looks perfect for this simple case, then as soon as I can I’ll delve more into the inner workings of the ValueTreeState attachments.  
Thanks for the clarifications.
