# Thread race in JuceVSTWrapper::createEditorComp

**URL:** <https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421>\
**Category:** Audio Plugins\
**Created:** [September 26, 2019, 10:26am UTC](https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421 "2019-09-26T10:26:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)\
**Post date:** [September 26, 2019, 10:26am UTC](https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421/1 "2019-09-26T10:26:43Z")

</div>

```
WARNING: ThreadSanitizer: data race (pid=7335)
Write of size 4 at 0x7b64001248a0 by main thread (mutexes: write M825701810479044344):
#0 JuceVSTWrapper::createEditorComp() juce_VST_Wrapper.cpp:1138 (Analog Rytm:x86_64+0x1c955)
#1 JuceVSTWrapper::handleGetEditorBounds(JuceVSTWrapper::VstOpCodeArguments) juce_VST_Wrapper.cpp:1816 (Analog Rytm:x86_64+0x14e18)
#2 JuceVSTWrapper::dispatcher(int, JuceVSTWrapper::VstOpCodeArguments) juce_VST_Wrapper.cpp:1205 (Analog Rytm:x86_64+0x13241)
#3 JuceVSTWrapper::dispatcherCB(Vst2::AEffect*, int, int, long long, void*, float) juce_VST_Wrapper.cpp:1252 (Analog Rytm:x86_64+0x9f6f)
#4 juce::VSTPluginInstance::dispatch(int, int, long long, void*, float) const juce_VSTPluginFormat.cpp:1751 (pluginval:x86_64+0x1000ae339)
#5 juce::VSTPluginWindow::dispatch(int, int, int, void*, float) juce_VSTPluginFormat.cpp:3279 (pluginval:x86_64+0x100174962)
#6 juce::VSTPluginWindow::VSTPluginWindow(juce::VSTPluginInstance&) juce_VSTPluginFormat.cpp:2798 (pluginval:x86_64+0x100174450)
#7 juce::VSTPluginWindow::VSTPluginWindow(juce::VSTPluginInstance&) juce_VSTPluginFormat.cpp:2772 (pluginval:x86_64+0x1000ac928)
#8 juce::VSTPluginInstance::createEditor() juce_VSTPluginFormat.cpp:3486 (pluginval:x86_64+0x1000ac848)
#9 BackgroundThreadStateTest::runTest(PluginTests&, juce::AudioPluginInstance&)::'lambda'()::operator()() const BasicTests.cpp:415 (pluginval:x86_64+0x100079256)
#10 void std:: __1::__ invoke_void_return_wrapper<void>::__call<BackgroundThreadStateTest::runTest(PluginTests&, juce::AudioPluginInstance&)::'lambda'()&>(BackgroundThreadStateTest::runTest(PluginTests&, juce::AudioPluginInstance&)::'lambda'()&&&) type_traits:4345 (pluginval:x86_64+0x100079190)
#11 std:: __1::__ function::__func<BackgroundThreadStateTest::runTest(PluginTests&, juce::AudioPluginInstance&)::'lambda'(), std::__1::allocator<BackgroundThreadStateTest::runTest(PluginTests&, juce::AudioPluginInstance&)::'lambda'()>, void ()>::operator()() functional:1562 (pluginval:x86_64+0x100078fbc)
#12 std::__1::function<void ()>::operator()() const functional:1913 (pluginval:x86_64+0x10006054e)
#13 juce::MessageManager::callAsync(std::__1::function<void ()>)::AsyncCallInvoker::messageCallback() juce_MessageManager.cpp:192 (pluginval:x86_64+0x1008f669c)
#14 juce::MessageQueue::deliverNextMessage() juce_osx_MessageQueue.h:82 (pluginval:x86_64+0x100908ec6)
#15 juce::MessageQueue::runLoopCallback() juce_osx_MessageQueue.h:93 (pluginval:x86_64+0x100908de9)
#16 juce::MessageQueue::runLoopSourceCallback(void*) juce_osx_MessageQueue.h:101 (pluginval:x86_64+0x100908bb8)
#17 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ <null> (CoreFoundation:x86_64h+0x57682)
#18 juce::JUCEApplicationBase::main() juce_ApplicationBase.cpp:262 (pluginval:x86_64+0x1008df20c)
#19 juce::JUCEApplicationBase::main(int, char const**) juce_ApplicationBase.cpp:240 (pluginval:x86_64+0x1008dec05)
#20 main Main.cpp:183 (pluginval:x86_64+0x10001051c)

Previous read of size 4 at 0x7b64001248a0 by thread T8:
#0 juce::VSTPluginInstance::usesChunks() const juce_VSTPluginFormat.cpp:1957 (pluginval:x86_64+0x10018d5c4)
#1 juce::VSTPluginInstance::getChunkData(juce::MemoryBlock&, bool, int) const juce_VSTPluginFormat.cpp:1961 (pluginval:x86_64+0x1000b21f4)
#2 juce::VSTPluginInstance::saveToFXBFile(juce::MemoryBlock&, bool, int) juce_VSTPluginFormat.cpp:1870 (pluginval:x86_64+0x1000b16be)
#3 juce::VSTPluginInstance::getStateInformation(juce::MemoryBlock&) juce_VSTPluginFormat.cpp:1611 (pluginval:x86_64+0x100140a72)
#4 BackgroundThreadStateTest::runTest(PluginTests&, juce::AudioPluginInstance&) BasicTests.cpp:431 (pluginval:x86_64+0x100076876)
#5 PluginTests::testType(juce::PluginDescription const&) PluginTests.cpp:153 (pluginval:x86_64+0x100037182)
#6 PluginTests::runTest() PluginTests.cpp:90 (pluginval:x86_64+0x100035f46)
#7 juce::UnitTest::performTest(juce::UnitTestRunner*) juce_UnitTest.cpp:77 (pluginval:x86_64+0x100790c1d)
#8 juce::UnitTestRunner::runTests(juce::Array<juce::UnitTest*, juce::DummyCriticalSection, 0> const&, long long) juce_UnitTest.cpp:165 (pluginval:x86_64+0x1007920d4)
#9 runTests(PluginTests&, std::__1::function<void (juce::String const&)>) Validator.cpp:106 (pluginval:x86_64+0x1000580b7)
#10 validate(juce::String const&, PluginTests::Options, std::__1::function<void (juce::String const&)>) Validator.cpp:123 (pluginval:x86_64+0x100057821)
#11 ValidatorSlaveProcess::processRequest(juce::MemoryBlock) Validator.cpp:383 (pluginval:x86_64+0x100055858)
#12 ValidatorSlaveProcess::processRequests() Validator.cpp:352 (pluginval:x86_64+0x100054562)
#13 ValidatorSlaveProcess::run() Validator.cpp:319 (pluginval:x86_64+0x100051152)
#14 non-virtual thunk to ValidatorSlaveProcess::run() Validator.cpp (pluginval:x86_64+0x10005138c)
#15 juce::Thread::threadEntryPoint() juce_Thread.cpp:96 (pluginval:x86_64+0x10078375c)
#16 juce::juce_threadEntryPoint(void*) juce_Thread.cpp:118 (pluginval:x86_64+0x100783f78)
#17 juce::threadEntryProc(void*) juce_posix_SharedCode.h:896 (pluginval:x86_64+0x1007d80b9)

Location is heap block of size 1184 at 0x7b6400124800 allocated by main thread:
#0 operator new(unsigned long) <null> (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x4ec7b)
#1 (anonymous namespace)::pluginEntryPoint(long long (*)(Vst2::AEffect*, int, int, long long, void*, float)) juce_VST_Wrapper.cpp:2341 (Analog Rytm:x86_64+0x7c24)
#2 main_macho juce_VST_Wrapper.cpp:2386 (Analog Rytm:x86_64+0x7eec)
#3 juce::VSTPluginInstance::constructEffect(juce::ReferenceCountedObjectPtr<juce::ModuleHandle> const&) juce_VSTPluginFormat.cpp:2175 (pluginval:x86_64+0x10017868c)
#4 juce::VSTPluginInstance::create(juce::ReferenceCountedObjectPtr<juce::ModuleHandle> const&, double, int) juce_VSTPluginFormat.cpp:1165 (pluginval:x86_64+0x1000af983)
#5 juce::VSTPluginFormat::createPluginInstance(juce::PluginDescription const&, double, int, std::__1::function<void (std::__1::unique_ptr<juce::AudioPluginInstance, std::__1::default_delete<juce::AudioPluginInstance> >, juce::String const&)>) juce_VSTPluginFormat.cpp:3597 (pluginval:x86_64+0x1000ae7da)
#6 juce::AudioPluginFormat::handleMessage(juce::Message const&) juce_AudioPluginFormat.cpp:96 (pluginval:x86_64+0x100086e4f)
#7 juce::Message::messageCallback() juce_MessageListener.cpp:32 (pluginval:x86_64+0x1008e07a1)
#8 juce::MessageQueue::deliverNextMessage() juce_osx_MessageQueue.h:82 (pluginval:x86_64+0x100908ec6)
#9 juce::MessageQueue::runLoopCallback() juce_osx_MessageQueue.h:93 (pluginval:x86_64+0x100908de9)
#10 juce::MessageQueue::runLoopSourceCallback(void*) juce_osx_MessageQueue.h:101 (pluginval:x86_64+0x100908bb8)
#11 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ <null> (CoreFoundation:x86_64h+0x57682)
#12 juce::JUCEApplicationBase::main() juce_ApplicationBase.cpp:262 (pluginval:x86_64+0x1008df20c)
#13 juce::JUCEApplicationBase::main(int, char const**) juce_ApplicationBase.cpp:240 (pluginval:x86_64+0x1008dec05)
#14 main Main.cpp:183 (pluginval:x86_64+0x10001051c)

  Mutex M825701810479044344 is already destroyed.

 Thread T8 (tid=49897, running) created by main thread at:
#0 pthread_create <null> (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x89dd)
#1 juce::Thread::launchThread() juce_posix_SharedCode.h:953 (pluginval:x86_64+0x1007841b9)
#2 juce::Thread::startThread() juce_Thread.cpp:130 (pluginval:x86_64+0x100784028)
#3 juce::Thread::startThread(int) juce_Thread.cpp:152 (pluginval:x86_64+0x1007844fb)
#4 ValidatorSlaveProcess::ValidatorSlaveProcess() Validator.cpp:201 (pluginval:x86_64+0x100050c61)
#5 ValidatorSlaveProcess::ValidatorSlaveProcess() Validator.cpp:196 (pluginval:x86_64+0x100050798)
#6 ValidatorMasterProcess::launchInProcess() memory:3114 (pluginval:x86_64+0x10004d11c)
#7 Validator::ensureConnection() Validator.cpp:640 (pluginval:x86_64+0x10004b787)
#8 Validator::validate(juce::StringArray const&, PluginTests::Options) Validator.cpp:592 (pluginval:x86_64+0x10004adb5)
#9 CommandLineValidator::validate(juce::StringArray const&, PluginTests::Options, bool) CommandLine.cpp:102 (pluginval:x86_64+0x100008d04)
#10 validate(CommandLineValidator&, juce::StringArray const&) CommandLine.cpp:270 (pluginval:x86_64+0x10000c871)
#11 performCommandLine(CommandLineValidator&, juce::String const&) CommandLine.cpp:410 (pluginval:x86_64+0x10000b2f7)
#12 PluginValidatorApplication::handleAsyncUpdate() Main.cpp:177 (pluginval:x86_64+0x1000132e7)
#13 non-virtual thunk to PluginValidatorApplication::handleAsyncUpdate() Main.cpp (pluginval:x86_64+0x1000134ac)
#14 juce::AsyncUpdater::AsyncUpdaterMessage::messageCallback() juce_AsyncUpdater.cpp:34 (pluginval:x86_64+0x1008f89e3)
#15 juce::MessageQueue::deliverNextMessage() juce_osx_MessageQueue.h:82 (pluginval:x86_64+0x100908ec6)
#16 juce::MessageQueue::runLoopCallback() juce_osx_MessageQueue.h:93 (pluginval:x86_64+0x100908de9)
#17 juce::MessageQueue::runLoopSourceCallback(void*) juce_osx_MessageQueue.h:101 (pluginval:x86_64+0x100908bb8)
#18 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ <null> (CoreFoundation:x86_64h+0x57682)
#19 juce::JUCEApplicationBase::main() juce_ApplicationBase.cpp:262 (pluginval:x86_64+0x1008df20c)
#20 juce::JUCEApplicationBase::main(int, char const**) juce_ApplicationBase.cpp:240 (pluginval:x86_64+0x1008dec05)
#21 main Main.cpp:183 (pluginval:x86_64+0x10001051c)

SUMMARY: ThreadSanitizer: data race juce_VST_Wrapper.cpp:1138 in JuceVSTWrapper::createEditorComp()
```

---

<div class="post-metadata">

**Author:** ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)\
**Post date:** [October 3, 2019, 7:57am UTC](https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421/2 "2019-10-03T07:57:41Z")

</div>

bump 🙂

---

<div class="post-metadata">

**Author:** ![t0m](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/t0m/32/16413_2.png) [@t0m](https://forum.juce.com/u/t0m)\
**Post date:** [October 3, 2019, 9:28am UTC](https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421/3 "2019-10-03T09:28:32Z")

</div>

I’m afraid I’m struggling to reproduce this, and it’s not clear from your sanitizer trace exactly what the race is…

---

<div class="post-metadata">

**Author:** ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)\
**Post date:** [October 3, 2019, 10:27am UTC](https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421/4 "2019-10-03T10:27:49Z")

</div>

It looks like it is vstEffect.flags that are accessed from two threads.

![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/5/587b81ffcd6b8480cf9462b578d422bc9a4c7963.png)  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/9/936ba67cab30bda63ad8e58630a1e3ecd6b10956.png)

---

<div class="post-metadata">

**Author:** ![t0m](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/t0m/32/16413_2.png) [@t0m](https://forum.juce.com/u/t0m)\
**Post date:** [October 4, 2019, 9:29am UTC](https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421/5 "2019-10-04T09:29:15Z")

</div>

Thank you.

> <https://github.com/WeAreROLI/JUCE/commit/3403617f777b965f5a5550a8c74b60cd452ab793>

---

<div class="post-metadata">

**Author:** ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)\
**Post date:** [October 6, 2019, 10:06am UTC](https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421/6 "2019-10-06T10:06:26Z")

</div>

Thread sanitizer still reports that there is a race. I guess it is setting the flag in `createEditorComp()`

```
 vstEffect.flags = vstEffectAtomicFlags;

```

and then reading it in `usesChunks()` that is what thread sanitizer complains about. The `flags` member is an `int32_t`. That should be possibe to read and write atomically on x86, right?

If so maybe this is not a big problem, but it would be nice to get rid of the warning so that it is possible to run thread sanitizer in this context, and with that one could catch other problems. It is difficult to catch real issues in automation if there is a warning like this which is not silenced.

One possibility could be to use an attribute on those two functions. [https://chromium.googlesource.com/external/llvm.org/clang/+/google/stable/docs/ThreadSanitizer.rst#96](https://chromium.googlesource.com/external/llvm.org/clang/+/google/stable/docs/ThreadSanitizer.rst#96)

```
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
#define JUCE_NO_THREAD_SANITIZER __attribute__ ((no_sanitize("thread")))
#else
#define JUCE_NO_THREAD_SANITIZER
#endif
#else
#define JUCE_NO_THREAD_SANITIZER
#endif
```

---

<div class="post-metadata">

**Author:** ![t0m](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/t0m/32/16413_2.png) [@t0m](https://forum.juce.com/u/t0m)\
**Post date:** [October 7, 2019, 2:47pm UTC](https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421/7 "2019-10-07T14:47:37Z")

</div>

OK, I’ve had another attempt:

> <https://github.com/WeAreROLI/JUCE/commit/1003579c5acbf091370a6ca3df4c4d5031056206>

If tsan is still getting triggered then we’ll look at suppressing the sanitiser.

---

<div class="post-metadata">

**Author:** ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)\
**Post date:** [October 16, 2019, 1:09pm UTC](https://forum.juce.com/t/thread-race-in-jucevstwrapper-createeditorcomp/35421/8 "2019-10-16T13:09:39Z")

</div>

Warning is gone now. Great!
