I’ve been investigating an intermittent crash today and it seems to come down to the String class assignment operator not being threadsafe:
const String& String::operator= (const String& other) throw()
if (this != &other)
if (Atomic::decrementAndReturn (text->refCount) == 0) juce_free (text); text = other.text; } return *this;
My scenario is fairly simple:
non-message thread is assigning different status messages to a String and calling triggerAsyncUpdate (a lot);
message thread is assigning the status message String to a label.
By the way, I was being careful and using a critical section, but got caught out with a const String& returning outside of the critical section. Once I replaced this with a const String return everything seems OK.
What seemed to be happening was that both threads managed to call String::operator= at the same time. The first one decrements refCount to zero and calls free. Then, before it gets a chance to execute text = other.text, the second thread increments the ref count to one and copies the free’d text. Next time round the text is free’d for a second time, causing the crash.
Obviously, using a Critical Section and being very careful with const String& solves the problem, but I wonder if anyone else has any thoughts on this.