Multiple Random Assertions on isValidComponent()

Hi, I have spent days trying to figure this out so thought I would finally ask here in-case I am missing something obvious or someone else has encountered this issue.

Recently I re-worked my application to create a ValueTree from a series of default values and then have my components reference the values to sort of centralise the controls. This means I can modify the ValueTree from different places and all my components will update accordingly. I can also very easily save the state of this and reload it so thanks for this truly magnificent class. I’m not sure if this is the cause of the problem but this was what I added when I started to notice the problem.

Now for some unknown reason I keep hitting assertions for isValidComponent(). These get hit from various places such as addComponentListener(), removeComponentListener(), isParentOf() etc. and as far as I can tell is completely random. It happens to different components only occasionally, sometimes more frequently than others and sometimes not at all. It doesn’t seem to affect my application as it all seems to work fine but obviously keeps launching the debugger every time I hit one. It also happens to components that aren’t linked to the ValueTree which makes me think it’s not to do with that.

What I can’t understand is how something can be a valid component one minute and not another, it all draws ok and I’m not creating or deleting any components after initial construction. From the stack trace both “this” and “newListener” or whatever the argument is have an address.

This has got me perplexed so any pointers oh hints would be very welcome.

OSX, JUCE v1.52.36

The only way I could think in which ValueTree could be involved would be if you register a component as a ValueTree::Listener and then delete the component without unregistering it from the tree…?

Do you use a static ValueTree object somewhere ?
I had these until I’ve changed the code to :

  ValueTree & getMainTree() { static ValueTree tree; return tree; }

Then it’ll be created when on first use, and not before the message thread is started (which leads to assertions crazyness you describe).

Sort of but I use the Singleton macros and DeletedAtShutdown classes then I create the instance of it first in my JUCEApplication::initialise() method so it should be around for the lifetime of my program.

I have made sure that all the classes that listen to the tree remove themselves at the start of their destructor’s so there shouldn’t be any dangling listeners. I also don’t delete any of the components before shutdown so don’t understand how they can be null. Also how can isValidComponent() be called from within a class (ie. without an object) if it checks to see if it has been deleted. Surely if the object had been deleted there would be no instance of itself to call the method on? Or am I missing something here?

I might have to duplicate the program without the ValueTree to see if this problem persists but the more I think about it the more I don’t think it could be due to the tree.

Quick update on this in case any one is interested. I think I have traced the problem to a multi-threading issue. I use the ValueTree in mu audio callback to mix various source players. Not 100% sure how all this works but I guess if the audio thread is reading a value from the tree then the message thread tries to read the same value to update a component is can appear the component is not valid?

Now as I’m pretty new to thread safety I was hoping someone could help point me in the direction of a solution. I had a couple of quick thoughts:

  1. Create a parent class to hold the audio callback which holds a set of Atomics and this becomes the ValueTree::Listener. The ValueTree callbacks then set the atomics and the audio callback will read these for its processing.

  2. Similar to the above except that normal variables are used and a CriticalSection is created around the ValueTree callback.

As this is quite a CPU intensive program I need it to be fast and not block wither thread for more time than necessary. Many thanks in advance.


Ah, the ValueTree stuff isn’t designed for thread-safety, maybe you just need to add some locking if you’re going to use it like that.