-
Notifications
You must be signed in to change notification settings - Fork 229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Opening states on macOS almost crashes Bespoke #21
Comments
this does not occur for me. can you post an example .bsk file that crashes for you, so I can try to reproduce it and find more info? |
For example, this file: https://transfer.sh/zqV62/2020-08-15_14-42.bsk. (GitHub gist wasn’t working unfortunately because the file is too large.) |
hmm, unfortunately this file will not download for me, I don't seem to be able to access transfer.sh if possible, you could email it to me at my username @gmail.com |
thank you, I received the .bsk that you sent! it also crashes for me when I load it. it appears to be crashing when loading the "sampler" module, so I likely have some bug in the savestate for sampler modules. I can't recreate a crashing save file locally, so it must be caused by something more subtle, I will keep digging to figure out what's going on. if I short-circuit the sampler loading in code, the rest of your .bsk file opens fine. in the meantime: can you still get the crash if you don't use a "sampler" module? if not, I would advise avoiding the sampler module for now. |
Thank you! Yes, it also crashes when I try to open the patch without a sampler module. |
hmm! so to test the very basics of saving: if you just load straight into bespoke and don't add any modules, then save state, then load that basic state, does it crash? if it does, can you send that .bsk to me? |
The basic state loads very quickly and without problems. |
gotcha. so, it sounds like there must be certain modules that don't serialize correctly, either due to a bug that effects everybody, or an issue specific to your machine's configuration. if you have the time, creating the simplest possible patch that still crashes when you try to load it would be helpful to narrow down the issue. |
on loading the example__scripting.bsk file, on bespoke version 1.0.0, on an M1 Apple Sillicon Mac Mini running OS 11.3, Bespoke plays a tiny sound, and then exits. I don't get an OS X "This app unexpectedly quit" notification like I usually do. |
stale issue, let's close this! |
ThreadSanitizer identifies a few data races involving the ModularSynth::mPixelRatio variable. For instance, appendix A, where MainContentComponent::render() reads mPixelRatio while holding ModularSynth::mRenderLock: void render() override { mSynth.LockRender(true); // ... glViewport(0, 0, width * mPixelRatio, height * mPixelRatio); // ... mSynth.LockRender(false); // ... } ... but MainContentComponent::timerCallback() writes mPixelRatio without holding mRenderLock: void timerCallback() override { //... if (sRenderFrame % 30 == 0) { if (const auto* dpy = Desktop::getInstance().getDisplays().getDisplayForRect(getScreenBounds())) { mPixelRatio = dpy->scale; //adjust pixel ratio based on which screen has the majority of the window TheSynth->SetPixelRatio(mPixelRatio); } } // ... } This commit changes ModularSynth::SetPixelRatio() to automatically hold mRenderLock while accessing mPixelRatio. ModularSynth::GetPixelRatio() is not changed to hold mRenderLock, because it is declared const, which prohibits locking/unlocking. Callers must ensure that GetPixelRatio() is called with mRenderLock already held (such as in Appendix B). This particular case may be benign, but it obscures other bugs in the flood of output from ThreadSanitizer. Appendix A: ``` WARNING: ThreadSanitizer: data race (pid=1608595) Read of size 8 at 0x7b8000056e48 by thread T9 (mutexes: write M19877): #0 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:357 (BespokeSynth+0x5f35aa) #1 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #2 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #3 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #4 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) #5 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) #6 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) #7 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) #8 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Previous write of size 8 at 0x7b8000056e48 by main thread: #0 non-virtual thunk to MainContentComponent::timerCallback() <null> (BespokeSynth+0x5f11ad) #1 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115 (BespokeSynth+0xe63c3e) #2 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181 (BespokeSynth+0xe63d27) #3 juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42 (BespokeSynth+0xe64273) #4 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe64407) #5 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe64407) #6 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe64407) #7 std::function<void (int)>::operator()(int) const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe51c30) #8 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359 (BespokeSynth+0xe51c30) #9 __invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe51c30) BespokeSynth#10 __invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe51c30) BespokeSynth#11 _M_invoke /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe51c30) BespokeSynth#12 std::function<void ()>::operator()() const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe60bff) BespokeSynth#13 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182 (BespokeSynth+0xe60bff) BespokeSynth#14 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342 (BespokeSynth+0xe60bff) BespokeSynth#15 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109 (BespokeSynth+0xe60d7e) BespokeSynth#16 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262 (BespokeSynth+0x3f8c36) BespokeSynth#17 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#18 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Location is heap block of size 3688 at 0x7b8000056000 allocated by main thread: #0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.2+0x87323) #1 createMainContentComponent() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:588 (BespokeSynth+0x5f0c69) #2 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:101 (BespokeSynth+0x5f010a) #3 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f010a) #4 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f010a) #5 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) #6 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) #7 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) #8 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) #9 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Mutex M19877 (0x7b8000056ce0) created at: #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4324 (libtsan.so.2+0x558e1) #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749 (BespokeSynth+0x5f34b6) #2 __gthread_recursive_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811 (BespokeSynth+0x5f34b6) #3 std::recursive_mutex::lock() /usr/include/c++/12/mutex:108 (BespokeSynth+0x5f34b6) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226 (BespokeSynth+0x5f34b6) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:345 (BespokeSynth+0x5f34b6) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #8 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#13 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Thread T9 (tid=1608673, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5e686) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919 (BespokeSynth+0xda95ef) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130 (BespokeSynth+0xdac173) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117 (BespokeSynth+0xdac4e8) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97 (BespokeSynth+0xdc9809) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x13dcb23) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163 (BespokeSynth+0x13dcb23) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039 (BespokeSynth+0x13dcb23) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016 (BespokeSynth+0x13dcb23) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952 (BespokeSynth+0x13dd249) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120 (BespokeSynth+0x113d764) BespokeSynth#11 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#12 callChecked<juce::Component::sendVisibilityChangeMessage()::<lambda(juce::ComponentListener&)>, juce::Component::BailOutChecker> /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170 (BespokeSynth+0x1104d77) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609 (BespokeSynth+0x117bf02) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105 (BespokeSynth+0x5f015d) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f015d) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f015d) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:357 in MainContentComponent::render() ``` Appendix B: ``` WARNING: ThreadSanitizer: data race (pid=1608595) Read of size 8 at 0x7b8000056dc8 by thread T9 (mutexes: write M19877): #0 ModularSynth::GetPixelRatio() const /home/jn/dev/synth/bespoke/Source/ModularSynth.h:168 (BespokeSynth+0xa86e4f) #1 ofSetColor(float, float, float, float) /home/jn/dev/synth/bespoke/Source/OpenFrameworksPort.cpp:201 (BespokeSynth+0xa86e4f) #2 DrawLissajous(RollingBuffer*, float, float, float, float, float, float, float) /home/jn/dev/synth/bespoke/Source/SynthGlobals.cpp:528 (BespokeSynth+0xc4dcd1) #3 ModularSynth::Draw(void*) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:514 (BespokeSynth+0x64fa42) #4 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:377 (BespokeSynth+0x5f37e7) #5 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #6 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #8 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) #9 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#10 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#11 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#12 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Previous write of size 8 at 0x7b8000056dc8 by main thread: #0 non-virtual thunk to MainContentComponent::timerCallback() <null> (BespokeSynth+0x5f11d3) #1 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115 (BespokeSynth+0xe63c3e) #2 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181 (BespokeSynth+0xe63d27) #3 juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42 (BespokeSynth+0xe64273) #4 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe64407) #5 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe64407) #6 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe64407) #7 std::function<void (int)>::operator()(int) const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe51c30) #8 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359 (BespokeSynth+0xe51c30) #9 __invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe51c30) BespokeSynth#10 __invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe51c30) BespokeSynth#11 _M_invoke /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe51c30) BespokeSynth#12 std::function<void ()>::operator()() const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe60bff) BespokeSynth#13 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182 (BespokeSynth+0xe60bff) BespokeSynth#14 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342 (BespokeSynth+0xe60bff) BespokeSynth#15 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109 (BespokeSynth+0xe60d7e) BespokeSynth#16 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262 (BespokeSynth+0x3f8c36) BespokeSynth#17 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#18 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Location is heap block of size 3688 at 0x7b8000056000 allocated by main thread: #0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.2+0x87323) #1 createMainContentComponent() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:588 (BespokeSynth+0x5f0c69) #2 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:101 (BespokeSynth+0x5f010a) #3 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f010a) #4 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f010a) #5 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) #6 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) #7 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) #8 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) #9 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Mutex M19877 (0x7b8000056ce0) created at: #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4324 (libtsan.so.2+0x558e1) #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749 (BespokeSynth+0x5f34b6) #2 __gthread_recursive_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811 (BespokeSynth+0x5f34b6) #3 std::recursive_mutex::lock() /usr/include/c++/12/mutex:108 (BespokeSynth+0x5f34b6) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226 (BespokeSynth+0x5f34b6) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:345 (BespokeSynth+0x5f34b6) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #8 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#13 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Thread T9 (tid=1608673, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5e686) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919 (BespokeSynth+0xda95ef) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130 (BespokeSynth+0xdac173) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117 (BespokeSynth+0xdac4e8) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97 (BespokeSynth+0xdc9809) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x13dcb23) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163 (BespokeSynth+0x13dcb23) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039 (BespokeSynth+0x13dcb23) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016 (BespokeSynth+0x13dcb23) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952 (BespokeSynth+0x13dd249) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120 (BespokeSynth+0x113d764) BespokeSynth#11 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#12 callChecked<juce::Component::sendVisibilityChangeMessage()::<lambda(juce::ComponentListener&)>, juce::Component::BailOutChecker> /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170 (BespokeSynth+0x1104d77) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609 (BespokeSynth+0x117bf02) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105 (BespokeSynth+0x5f015d) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f015d) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f015d) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/ModularSynth.h:168 in ModularSynth::GetPixelRatio() const ```
ThreadSanitizer reports a race condition between LocationZoomer::Update() and ModularSynth::Draw(): void LocationZoomer::Update() { if (mCurrentProgress < 1) { // ... gDrawScale = ofLerp(mStart.mZoomLevel, mDestination.mZoomLevel, ease); // A ofVec2f offset; offset.x = ofLerp(mStart.mOffset.x, mDestination.mOffset.x, ease); offset.y = ofLerp(mStart.mOffset.y, mDestination.mOffset.y, ease); TheSynth->SetDrawOffset(offset); // B // ... } } void ModularSynth::Draw(void* vg) { // ... mDrawRect.set(-GetDrawOffset().x, -GetDrawOffset().y, ofGetWidth() / gDrawScale, ofGetHeight() / gDrawScale); // ... } Draw() is called from the render thread, with the render lock held, and Update() is called from the timer thread, without any locks held. This commit changes LocationZoomer::Update to hold ModularSynth::mLockRender. An partial alternative would be to: - change ModularSynth::SetDrawOffset() to hold mRenderLock automatically. - add locking to SynthGlobals.h, and take the lock for gDrawScale in LocationZoomer::Update() ``` WARNING: ThreadSanitizer: data race (pid=1608595) Read of size 4 at 0x555557038004 by thread T9 (mutexes: write M19877): #0 ModularSynth::Draw(void*) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:491 (BespokeSynth+0x64dcaa) #1 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:377 (BespokeSynth+0x5f37e7) #2 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #3 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #4 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #5 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) #6 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) #7 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) #8 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) #9 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Previous write of size 4 at 0x555557038004 by main thread: #0 LocationZoomer::Update() /home/jn/dev/synth/bespoke/Source/LocationZoomer.cpp:57 (BespokeSynth+0x5c6e69) #1 ModularSynth::Poll() /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:345 (BespokeSynth+0x656a0a) #2 non-virtual thunk to MainContentComponent::timerCallback() <null> (BespokeSynth+0x5f111b) #3 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115 (BespokeSynth+0xe63c3e) #4 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181 (BespokeSynth+0xe63d27) #5 juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42 (BespokeSynth+0xe64273) #6 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe64407) #7 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe64407) #8 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe64407) #9 std::function<void (int)>::operator()(int) const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe51c30) BespokeSynth#10 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359 (BespokeSynth+0xe51c30) BespokeSynth#11 __invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe51c30) BespokeSynth#12 __invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe51c30) BespokeSynth#13 _M_invoke /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe51c30) BespokeSynth#14 std::function<void ()>::operator()() const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe60bff) BespokeSynth#15 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182 (BespokeSynth+0xe60bff) BespokeSynth#16 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342 (BespokeSynth+0xe60bff) BespokeSynth#17 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109 (BespokeSynth+0xe60d7e) BespokeSynth#18 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262 (BespokeSynth+0x3f8c36) BespokeSynth#19 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#20 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Location is global 'gDrawScale' of size 4 at 0x555557038004 (BespokeSynth+0x1ae4004) Mutex M19877 (0x7b8000056ce0) created at: #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4324 (libtsan.so.2+0x558e1) #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749 (BespokeSynth+0x5f34b6) #2 __gthread_recursive_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811 (BespokeSynth+0x5f34b6) #3 std::recursive_mutex::lock() /usr/include/c++/12/mutex:108 (BespokeSynth+0x5f34b6) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226 (BespokeSynth+0x5f34b6) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:345 (BespokeSynth+0x5f34b6) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #8 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#13 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Thread T9 (tid=1608673, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5e686) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919 (BespokeSynth+0xda95ef) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130 (BespokeSynth+0xdac173) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117 (BespokeSynth+0xdac4e8) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97 (BespokeSynth+0xdc9809) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x13dcb23) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163 (BespokeSynth+0x13dcb23) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039 (BespokeSynth+0x13dcb23) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016 (BespokeSynth+0x13dcb23) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952 (BespokeSynth+0x13dd249) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120 (BespokeSynth+0x113d764) BespokeSynth#11 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#12 callChecked<juce::Component::sendVisibilityChangeMessage()::<lambda(juce::ComponentListener&)>, juce::Component::BailOutChecker> /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170 (BespokeSynth+0x1104d77) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609 (BespokeSynth+0x117bf02) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105 (BespokeSynth+0x5f015d) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f015d) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f015d) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:491 in ModularSynth::Draw(void*) ```
ThreadSanitizer identifies a few data races involving the ModularSynth::mPixelRatio variable. For instance, appendix A, where MainContentComponent::render() reads mPixelRatio while holding ModularSynth::mRenderLock: void render() override { mSynth.LockRender(true); // ... glViewport(0, 0, width * mPixelRatio, height * mPixelRatio); // ... mSynth.LockRender(false); // ... } ... but MainContentComponent::timerCallback() writes mPixelRatio without holding mRenderLock: void timerCallback() override { //... if (sRenderFrame % 30 == 0) { if (const auto* dpy = Desktop::getInstance().getDisplays().getDisplayForRect(getScreenBounds())) { mPixelRatio = dpy->scale; //adjust pixel ratio based on which screen has the majority of the window TheSynth->SetPixelRatio(mPixelRatio); } } // ... } This commit changes ModularSynth::SetPixelRatio() to automatically hold mRenderLock while accessing mPixelRatio. ModularSynth::GetPixelRatio() is not changed to hold mRenderLock, because it is declared const, which prohibits locking/unlocking. Callers must ensure that GetPixelRatio() is called with mRenderLock already held (such as in Appendix B). This particular case may be benign, but it obscures other bugs in the flood of output from ThreadSanitizer. Appendix A: ``` WARNING: ThreadSanitizer: data race (pid=1608595) Read of size 8 at 0x7b8000056e48 by thread T9 (mutexes: write M19877): #0 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:357 (BespokeSynth+0x5f35aa) #1 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #2 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #3 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #4 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) #5 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) #6 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) #7 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) #8 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Previous write of size 8 at 0x7b8000056e48 by main thread: #0 non-virtual thunk to MainContentComponent::timerCallback() <null> (BespokeSynth+0x5f11ad) #1 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115 (BespokeSynth+0xe63c3e) #2 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181 (BespokeSynth+0xe63d27) #3 juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42 (BespokeSynth+0xe64273) #4 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe64407) #5 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe64407) #6 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe64407) #7 std::function<void (int)>::operator()(int) const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe51c30) #8 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359 (BespokeSynth+0xe51c30) #9 __invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe51c30) BespokeSynth#10 __invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe51c30) BespokeSynth#11 _M_invoke /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe51c30) BespokeSynth#12 std::function<void ()>::operator()() const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe60bff) BespokeSynth#13 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182 (BespokeSynth+0xe60bff) BespokeSynth#14 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342 (BespokeSynth+0xe60bff) BespokeSynth#15 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109 (BespokeSynth+0xe60d7e) BespokeSynth#16 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262 (BespokeSynth+0x3f8c36) BespokeSynth#17 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#18 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Location is heap block of size 3688 at 0x7b8000056000 allocated by main thread: #0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.2+0x87323) #1 createMainContentComponent() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:588 (BespokeSynth+0x5f0c69) #2 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:101 (BespokeSynth+0x5f010a) #3 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f010a) #4 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f010a) #5 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) #6 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) #7 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) #8 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) #9 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Mutex M19877 (0x7b8000056ce0) created at: #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4324 (libtsan.so.2+0x558e1) #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749 (BespokeSynth+0x5f34b6) #2 __gthread_recursive_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811 (BespokeSynth+0x5f34b6) #3 std::recursive_mutex::lock() /usr/include/c++/12/mutex:108 (BespokeSynth+0x5f34b6) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226 (BespokeSynth+0x5f34b6) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:345 (BespokeSynth+0x5f34b6) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #8 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#13 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Thread T9 (tid=1608673, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5e686) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919 (BespokeSynth+0xda95ef) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130 (BespokeSynth+0xdac173) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117 (BespokeSynth+0xdac4e8) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97 (BespokeSynth+0xdc9809) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x13dcb23) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163 (BespokeSynth+0x13dcb23) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039 (BespokeSynth+0x13dcb23) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016 (BespokeSynth+0x13dcb23) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952 (BespokeSynth+0x13dd249) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120 (BespokeSynth+0x113d764) BespokeSynth#11 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#12 callChecked<juce::Component::sendVisibilityChangeMessage()::<lambda(juce::ComponentListener&)>, juce::Component::BailOutChecker> /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170 (BespokeSynth+0x1104d77) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609 (BespokeSynth+0x117bf02) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105 (BespokeSynth+0x5f015d) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f015d) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f015d) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:357 in MainContentComponent::render() ``` Appendix B: ``` WARNING: ThreadSanitizer: data race (pid=1608595) Read of size 8 at 0x7b8000056dc8 by thread T9 (mutexes: write M19877): #0 ModularSynth::GetPixelRatio() const /home/jn/dev/synth/bespoke/Source/ModularSynth.h:168 (BespokeSynth+0xa86e4f) #1 ofSetColor(float, float, float, float) /home/jn/dev/synth/bespoke/Source/OpenFrameworksPort.cpp:201 (BespokeSynth+0xa86e4f) #2 DrawLissajous(RollingBuffer*, float, float, float, float, float, float, float) /home/jn/dev/synth/bespoke/Source/SynthGlobals.cpp:528 (BespokeSynth+0xc4dcd1) #3 ModularSynth::Draw(void*) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:514 (BespokeSynth+0x64fa42) #4 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:377 (BespokeSynth+0x5f37e7) #5 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #6 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #8 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) #9 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#10 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#11 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#12 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Previous write of size 8 at 0x7b8000056dc8 by main thread: #0 non-virtual thunk to MainContentComponent::timerCallback() <null> (BespokeSynth+0x5f11d3) #1 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115 (BespokeSynth+0xe63c3e) #2 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181 (BespokeSynth+0xe63d27) #3 juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42 (BespokeSynth+0xe64273) #4 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe64407) #5 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe64407) #6 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe64407) #7 std::function<void (int)>::operator()(int) const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe51c30) #8 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359 (BespokeSynth+0xe51c30) #9 __invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe51c30) BespokeSynth#10 __invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe51c30) BespokeSynth#11 _M_invoke /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe51c30) BespokeSynth#12 std::function<void ()>::operator()() const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe60bff) BespokeSynth#13 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182 (BespokeSynth+0xe60bff) BespokeSynth#14 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342 (BespokeSynth+0xe60bff) BespokeSynth#15 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109 (BespokeSynth+0xe60d7e) BespokeSynth#16 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262 (BespokeSynth+0x3f8c36) BespokeSynth#17 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#18 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Location is heap block of size 3688 at 0x7b8000056000 allocated by main thread: #0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.2+0x87323) #1 createMainContentComponent() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:588 (BespokeSynth+0x5f0c69) #2 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:101 (BespokeSynth+0x5f010a) #3 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f010a) #4 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f010a) #5 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) #6 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) #7 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) #8 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) #9 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Mutex M19877 (0x7b8000056ce0) created at: #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4324 (libtsan.so.2+0x558e1) #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749 (BespokeSynth+0x5f34b6) #2 __gthread_recursive_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811 (BespokeSynth+0x5f34b6) #3 std::recursive_mutex::lock() /usr/include/c++/12/mutex:108 (BespokeSynth+0x5f34b6) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226 (BespokeSynth+0x5f34b6) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:345 (BespokeSynth+0x5f34b6) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #8 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#13 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Thread T9 (tid=1608673, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5e686) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919 (BespokeSynth+0xda95ef) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130 (BespokeSynth+0xdac173) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117 (BespokeSynth+0xdac4e8) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97 (BespokeSynth+0xdc9809) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x13dcb23) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163 (BespokeSynth+0x13dcb23) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039 (BespokeSynth+0x13dcb23) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016 (BespokeSynth+0x13dcb23) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952 (BespokeSynth+0x13dd249) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120 (BespokeSynth+0x113d764) BespokeSynth#11 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#12 callChecked<juce::Component::sendVisibilityChangeMessage()::<lambda(juce::ComponentListener&)>, juce::Component::BailOutChecker> /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170 (BespokeSynth+0x1104d77) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609 (BespokeSynth+0x117bf02) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105 (BespokeSynth+0x5f015d) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f015d) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f015d) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/ModularSynth.h:168 in ModularSynth::GetPixelRatio() const ```
ThreadSanitizer reports a race condition between LocationZoomer::Update() and ModularSynth::Draw(): void LocationZoomer::Update() { if (mCurrentProgress < 1) { // ... gDrawScale = ofLerp(mStart.mZoomLevel, mDestination.mZoomLevel, ease); // A ofVec2f offset; offset.x = ofLerp(mStart.mOffset.x, mDestination.mOffset.x, ease); offset.y = ofLerp(mStart.mOffset.y, mDestination.mOffset.y, ease); TheSynth->SetDrawOffset(offset); // B // ... } } void ModularSynth::Draw(void* vg) { // ... mDrawRect.set(-GetDrawOffset().x, -GetDrawOffset().y, ofGetWidth() / gDrawScale, ofGetHeight() / gDrawScale); // ... } Draw() is called from the render thread, with the render lock held, and Update() is called from the timer thread, without any locks held. This commit changes LocationZoomer::Update to hold ModularSynth::mLockRender. An partial alternative would be to: - change ModularSynth::SetDrawOffset() to hold mRenderLock automatically. - add locking to SynthGlobals.h, and take the lock for gDrawScale in LocationZoomer::Update() ``` WARNING: ThreadSanitizer: data race (pid=1608595) Read of size 4 at 0x555557038004 by thread T9 (mutexes: write M19877): #0 ModularSynth::Draw(void*) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:491 (BespokeSynth+0x64dcaa) #1 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:377 (BespokeSynth+0x5f37e7) #2 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #3 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #4 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #5 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) #6 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) #7 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) #8 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) #9 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Previous write of size 4 at 0x555557038004 by main thread: #0 LocationZoomer::Update() /home/jn/dev/synth/bespoke/Source/LocationZoomer.cpp:57 (BespokeSynth+0x5c6e69) #1 ModularSynth::Poll() /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:345 (BespokeSynth+0x656a0a) #2 non-virtual thunk to MainContentComponent::timerCallback() <null> (BespokeSynth+0x5f111b) #3 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115 (BespokeSynth+0xe63c3e) #4 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181 (BespokeSynth+0xe63d27) #5 juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42 (BespokeSynth+0xe64273) #6 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe64407) #7 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe64407) #8 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe64407) #9 std::function<void (int)>::operator()(int) const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe51c30) BespokeSynth#10 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359 (BespokeSynth+0xe51c30) BespokeSynth#11 __invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe51c30) BespokeSynth#12 __invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe51c30) BespokeSynth#13 _M_invoke /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe51c30) BespokeSynth#14 std::function<void ()>::operator()() const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe60bff) BespokeSynth#15 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182 (BespokeSynth+0xe60bff) BespokeSynth#16 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342 (BespokeSynth+0xe60bff) BespokeSynth#17 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109 (BespokeSynth+0xe60d7e) BespokeSynth#18 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262 (BespokeSynth+0x3f8c36) BespokeSynth#19 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#20 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Location is global 'gDrawScale' of size 4 at 0x555557038004 (BespokeSynth+0x1ae4004) Mutex M19877 (0x7b8000056ce0) created at: #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4324 (libtsan.so.2+0x558e1) #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749 (BespokeSynth+0x5f34b6) #2 __gthread_recursive_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811 (BespokeSynth+0x5f34b6) #3 std::recursive_mutex::lock() /usr/include/c++/12/mutex:108 (BespokeSynth+0x5f34b6) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226 (BespokeSynth+0x5f34b6) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:345 (BespokeSynth+0x5f34b6) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #8 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#13 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Thread T9 (tid=1608673, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5e686) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919 (BespokeSynth+0xda95ef) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130 (BespokeSynth+0xdac173) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117 (BespokeSynth+0xdac4e8) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97 (BespokeSynth+0xdc9809) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x13dcb23) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163 (BespokeSynth+0x13dcb23) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039 (BespokeSynth+0x13dcb23) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016 (BespokeSynth+0x13dcb23) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952 (BespokeSynth+0x13dd249) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120 (BespokeSynth+0x113d764) BespokeSynth#11 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#12 callChecked<juce::Component::sendVisibilityChangeMessage()::<lambda(juce::ComponentListener&)>, juce::Component::BailOutChecker> /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170 (BespokeSynth+0x1104d77) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609 (BespokeSynth+0x117bf02) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105 (BespokeSynth+0x5f015d) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f015d) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f015d) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:491 in ModularSynth::Draw(void*) ```
ThreadSanitizer identifies a few data races involving the ModularSynth::mPixelRatio variable. For instance, appendix A, where MainContentComponent::render() reads mPixelRatio while holding ModularSynth::mRenderLock: void render() override { mSynth.LockRender(true); // ... glViewport(0, 0, width * mPixelRatio, height * mPixelRatio); // ... mSynth.LockRender(false); // ... } ... but MainContentComponent::timerCallback() writes mPixelRatio without holding mRenderLock: void timerCallback() override { //... if (sRenderFrame % 30 == 0) { if (const auto* dpy = Desktop::getInstance().getDisplays().getDisplayForRect(getScreenBounds())) { mPixelRatio = dpy->scale; //adjust pixel ratio based on which screen has the majority of the window TheSynth->SetPixelRatio(mPixelRatio); } } // ... } This commit changes ModularSynth::SetPixelRatio() to automatically hold mRenderLock while accessing mPixelRatio. ModularSynth::GetPixelRatio() is not changed to hold mRenderLock, because it is declared const, which prohibits locking/unlocking. Callers must ensure that GetPixelRatio() is called with mRenderLock already held (such as in Appendix B). This particular case may be benign, but it obscures other bugs in the flood of output from ThreadSanitizer. Appendix A: ``` WARNING: ThreadSanitizer: data race (pid=1608595) Read of size 8 at 0x7b8000056e48 by thread T9 (mutexes: write M19877): #0 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:357 (BespokeSynth+0x5f35aa) #1 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #2 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #3 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #4 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) #5 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) #6 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) #7 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) #8 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Previous write of size 8 at 0x7b8000056e48 by main thread: #0 non-virtual thunk to MainContentComponent::timerCallback() <null> (BespokeSynth+0x5f11ad) #1 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115 (BespokeSynth+0xe63c3e) #2 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181 (BespokeSynth+0xe63d27) #3 juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42 (BespokeSynth+0xe64273) #4 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe64407) #5 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe64407) #6 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe64407) #7 std::function<void (int)>::operator()(int) const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe51c30) #8 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359 (BespokeSynth+0xe51c30) #9 __invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe51c30) BespokeSynth#10 __invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe51c30) BespokeSynth#11 _M_invoke /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe51c30) BespokeSynth#12 std::function<void ()>::operator()() const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe60bff) BespokeSynth#13 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182 (BespokeSynth+0xe60bff) BespokeSynth#14 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342 (BespokeSynth+0xe60bff) BespokeSynth#15 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109 (BespokeSynth+0xe60d7e) BespokeSynth#16 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262 (BespokeSynth+0x3f8c36) BespokeSynth#17 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#18 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Location is heap block of size 3688 at 0x7b8000056000 allocated by main thread: #0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.2+0x87323) #1 createMainContentComponent() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:588 (BespokeSynth+0x5f0c69) #2 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:101 (BespokeSynth+0x5f010a) #3 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f010a) #4 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f010a) #5 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) #6 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) #7 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) #8 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) #9 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Mutex M19877 (0x7b8000056ce0) created at: #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4324 (libtsan.so.2+0x558e1) #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749 (BespokeSynth+0x5f34b6) #2 __gthread_recursive_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811 (BespokeSynth+0x5f34b6) #3 std::recursive_mutex::lock() /usr/include/c++/12/mutex:108 (BespokeSynth+0x5f34b6) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226 (BespokeSynth+0x5f34b6) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:345 (BespokeSynth+0x5f34b6) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #8 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#13 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Thread T9 (tid=1608673, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5e686) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919 (BespokeSynth+0xda95ef) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130 (BespokeSynth+0xdac173) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117 (BespokeSynth+0xdac4e8) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97 (BespokeSynth+0xdc9809) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x13dcb23) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163 (BespokeSynth+0x13dcb23) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039 (BespokeSynth+0x13dcb23) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016 (BespokeSynth+0x13dcb23) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952 (BespokeSynth+0x13dd249) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120 (BespokeSynth+0x113d764) BespokeSynth#11 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#12 callChecked<juce::Component::sendVisibilityChangeMessage()::<lambda(juce::ComponentListener&)>, juce::Component::BailOutChecker> /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170 (BespokeSynth+0x1104d77) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609 (BespokeSynth+0x117bf02) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105 (BespokeSynth+0x5f015d) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f015d) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f015d) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:357 in MainContentComponent::render() ``` Appendix B: ``` WARNING: ThreadSanitizer: data race (pid=1608595) Read of size 8 at 0x7b8000056dc8 by thread T9 (mutexes: write M19877): #0 ModularSynth::GetPixelRatio() const /home/jn/dev/synth/bespoke/Source/ModularSynth.h:168 (BespokeSynth+0xa86e4f) #1 ofSetColor(float, float, float, float) /home/jn/dev/synth/bespoke/Source/OpenFrameworksPort.cpp:201 (BespokeSynth+0xa86e4f) #2 DrawLissajous(RollingBuffer*, float, float, float, float, float, float, float) /home/jn/dev/synth/bespoke/Source/SynthGlobals.cpp:528 (BespokeSynth+0xc4dcd1) #3 ModularSynth::Draw(void*) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:514 (BespokeSynth+0x64fa42) #4 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:377 (BespokeSynth+0x5f37e7) #5 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #6 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #8 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) #9 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#10 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#11 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#12 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Previous write of size 8 at 0x7b8000056dc8 by main thread: #0 non-virtual thunk to MainContentComponent::timerCallback() <null> (BespokeSynth+0x5f11d3) #1 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115 (BespokeSynth+0xe63c3e) #2 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181 (BespokeSynth+0xe63d27) #3 juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42 (BespokeSynth+0xe64273) #4 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe64407) #5 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe64407) #6 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe64407) #7 std::function<void (int)>::operator()(int) const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe51c30) #8 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359 (BespokeSynth+0xe51c30) #9 __invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe51c30) BespokeSynth#10 __invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe51c30) BespokeSynth#11 _M_invoke /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe51c30) BespokeSynth#12 std::function<void ()>::operator()() const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe60bff) BespokeSynth#13 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182 (BespokeSynth+0xe60bff) BespokeSynth#14 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342 (BespokeSynth+0xe60bff) BespokeSynth#15 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109 (BespokeSynth+0xe60d7e) BespokeSynth#16 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262 (BespokeSynth+0x3f8c36) BespokeSynth#17 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#18 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Location is heap block of size 3688 at 0x7b8000056000 allocated by main thread: #0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.2+0x87323) #1 createMainContentComponent() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:588 (BespokeSynth+0x5f0c69) #2 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:101 (BespokeSynth+0x5f010a) #3 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f010a) #4 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f010a) #5 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) #6 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) #7 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) #8 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) #9 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Mutex M19877 (0x7b8000056ce0) created at: #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4324 (libtsan.so.2+0x558e1) #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749 (BespokeSynth+0x5f34b6) #2 __gthread_recursive_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811 (BespokeSynth+0x5f34b6) #3 std::recursive_mutex::lock() /usr/include/c++/12/mutex:108 (BespokeSynth+0x5f34b6) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226 (BespokeSynth+0x5f34b6) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:345 (BespokeSynth+0x5f34b6) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #8 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#13 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Thread T9 (tid=1608673, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5e686) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919 (BespokeSynth+0xda95ef) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130 (BespokeSynth+0xdac173) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117 (BespokeSynth+0xdac4e8) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97 (BespokeSynth+0xdc9809) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x13dcb23) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163 (BespokeSynth+0x13dcb23) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039 (BespokeSynth+0x13dcb23) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016 (BespokeSynth+0x13dcb23) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952 (BespokeSynth+0x13dd249) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120 (BespokeSynth+0x113d764) BespokeSynth#11 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#12 callChecked<juce::Component::sendVisibilityChangeMessage()::<lambda(juce::ComponentListener&)>, juce::Component::BailOutChecker> /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170 (BespokeSynth+0x1104d77) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609 (BespokeSynth+0x117bf02) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105 (BespokeSynth+0x5f015d) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f015d) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f015d) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/ModularSynth.h:168 in ModularSynth::GetPixelRatio() const ```
ThreadSanitizer reports a race condition between LocationZoomer::Update() and ModularSynth::Draw(): void LocationZoomer::Update() { if (mCurrentProgress < 1) { // ... gDrawScale = ofLerp(mStart.mZoomLevel, mDestination.mZoomLevel, ease); // A ofVec2f offset; offset.x = ofLerp(mStart.mOffset.x, mDestination.mOffset.x, ease); offset.y = ofLerp(mStart.mOffset.y, mDestination.mOffset.y, ease); TheSynth->SetDrawOffset(offset); // B // ... } } void ModularSynth::Draw(void* vg) { // ... mDrawRect.set(-GetDrawOffset().x, -GetDrawOffset().y, ofGetWidth() / gDrawScale, ofGetHeight() / gDrawScale); // ... } Draw() is called from the render thread, with the render lock held, and Update() is called from the timer thread, without any locks held. This commit changes LocationZoomer::Update to hold ModularSynth::mLockRender. An partial alternative would be to: - change ModularSynth::SetDrawOffset() to hold mRenderLock automatically. - add locking to SynthGlobals.h, and take the lock for gDrawScale in LocationZoomer::Update() ``` WARNING: ThreadSanitizer: data race (pid=1608595) Read of size 4 at 0x555557038004 by thread T9 (mutexes: write M19877): #0 ModularSynth::Draw(void*) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:491 (BespokeSynth+0x64dcaa) #1 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:377 (BespokeSynth+0x5f37e7) #2 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #3 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #4 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #5 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) #6 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) #7 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) #8 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) #9 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Previous write of size 4 at 0x555557038004 by main thread: #0 LocationZoomer::Update() /home/jn/dev/synth/bespoke/Source/LocationZoomer.cpp:57 (BespokeSynth+0x5c6e69) #1 ModularSynth::Poll() /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:345 (BespokeSynth+0x656a0a) #2 non-virtual thunk to MainContentComponent::timerCallback() <null> (BespokeSynth+0x5f111b) #3 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115 (BespokeSynth+0xe63c3e) #4 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181 (BespokeSynth+0xe63d27) #5 juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42 (BespokeSynth+0xe64273) #6 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe64407) #7 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe64407) #8 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe64407) #9 std::function<void (int)>::operator()(int) const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe51c30) BespokeSynth#10 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359 (BespokeSynth+0xe51c30) BespokeSynth#11 __invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:61 (BespokeSynth+0xe51c30) BespokeSynth#12 __invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void(int)>, short int)::<lambda()>&> /usr/include/c++/12/bits/invoke.h:111 (BespokeSynth+0xe51c30) BespokeSynth#13 _M_invoke /usr/include/c++/12/bits/std_function.h:290 (BespokeSynth+0xe51c30) BespokeSynth#14 std::function<void ()>::operator()() const /usr/include/c++/12/bits/std_function.h:591 (BespokeSynth+0xe60bff) BespokeSynth#15 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182 (BespokeSynth+0xe60bff) BespokeSynth#16 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342 (BespokeSynth+0xe60bff) BespokeSynth#17 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109 (BespokeSynth+0xe60d7e) BespokeSynth#18 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262 (BespokeSynth+0x3f8c36) BespokeSynth#19 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#20 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) Location is global 'gDrawScale' of size 4 at 0x555557038004 (BespokeSynth+0x1ae4004) Mutex M19877 (0x7b8000056ce0) created at: #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4324 (libtsan.so.2+0x558e1) #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749 (BespokeSynth+0x5f34b6) #2 __gthread_recursive_mutex_lock /usr/include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811 (BespokeSynth+0x5f34b6) #3 std::recursive_mutex::lock() /usr/include/c++/12/mutex:108 (BespokeSynth+0x5f34b6) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226 (BespokeSynth+0x5f34b6) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:345 (BespokeSynth+0x5f34b6) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61 (BespokeSynth+0x13e6020) #7 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326 (BespokeSynth+0x13e6020) #8 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583 (BespokeSynth+0x13e6476) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384 (BespokeSynth+0xdc9896) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36 (BespokeSynth+0xe2550e) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96 (BespokeSynth+0xdd44c5) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118 (BespokeSynth+0xdd4655) BespokeSynth#13 threadEntryProc /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865 (BespokeSynth+0xdd4655) Thread T9 (tid=1608673, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5e686) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919 (BespokeSynth+0xda95ef) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130 (BespokeSynth+0xdac173) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117 (BespokeSynth+0xdac4e8) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97 (BespokeSynth+0xdc9809) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x13dcb23) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163 (BespokeSynth+0x13dcb23) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039 (BespokeSynth+0x13dcb23) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016 (BespokeSynth+0x13dcb23) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952 (BespokeSynth+0x13dd249) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120 (BespokeSynth+0x113d764) BespokeSynth#11 operator() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#12 callChecked<juce::Component::sendVisibilityChangeMessage()::<lambda(juce::ComponentListener&)>, juce::Component::BailOutChecker> /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170 (BespokeSynth+0x1104d77) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631 (BespokeSynth+0x1104d77) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609 (BespokeSynth+0x117bf02) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105 (BespokeSynth+0x5f015d) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/include/c++/12/bits/unique_ptr.h:1065 (BespokeSynth+0x5f015d) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50 (BespokeSynth+0x5f015d) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297 (BespokeSynth+0xe612a0) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92 (BespokeSynth+0x11ee365) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256 (BespokeSynth+0x3f8c25) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240 (BespokeSynth+0x3f8cbe) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134 (BespokeSynth+0x38b9b8) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:491 in ModularSynth::Draw(void*) ```
================== WARNING: ThreadSanitizer: data race (pid=795426) Read of size 4 at 0x7b6c00000e88 by thread T3 (mutexes: write M0): #0 IClickable::NotifyMouseMoved(float, float) /home/jn/dev/synth/bespoke/Source/IClickable.cpp:74:26 (BespokeSynth+0x60c873) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 ModuleContainer::MouseMoved(float, float) /home/jn/dev/synth/bespoke/Source/ModuleContainer.cpp:182:20 (BespokeSynth+0xa7a6c4) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 ModularSynth::MouseMoved(int, int) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:1288:24 (BespokeSynth+0x6b6d50) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:347:14 (BespokeSynth+0x6772f0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61:5 (BespokeSynth+0x14c8c72) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 non-virtual thunk to juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp (BespokeSynth+0x14c8c72) #6 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326:31 (BespokeSynth+0x14e1113) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583:19 (BespokeSynth+0x14df030) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 non-virtual thunk to juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp (BespokeSynth+0x14df19d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384:27 (BespokeSynth+0xe2e78b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36:24 (BespokeSynth+0xeaedd9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96:13 (BespokeSynth+0xe2a2c6) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118:38 (BespokeSynth+0xe6c3c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#13 juce::threadEntryProc(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865:9 (BespokeSynth+0xe6c3c9) Previous write of size 4 at 0x7b6c00000e88 by main thread: #0 IClickable::SetPosition(float, float) /home/jn/dev/synth/bespoke/Source/IClickable.h:44:10 (BespokeSynth+0x6b0333) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 ModularSynth::LoadLayoutFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2421:19 (BespokeSynth+0x6b0333) #2 ModularSynth::Poll() /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:350:13 (BespokeSynth+0x6aeea4) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:127:14 (BespokeSynth+0x677771) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 non-virtual thunk to MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp (BespokeSynth+0x677fd0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115:24 (BespokeSynth+0xf2426e) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #6 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181:27 (BespokeSynth+0xf2404b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42:62 (BespokeSynth+0xf270d7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf270d7) #9 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf26fb0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)>::_M_invoke(std::_Any_data const&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf26fb0) BespokeSynth#11 std::function<void (int)>::operator()(int) const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf209be) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3::operator()() const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359:80 (BespokeSynth+0xf209be) BespokeSynth#13 void std::__invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(std::__invoke_other, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf209be) BespokeSynth#14 std::enable_if<is_invocable_r_v<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>, void>::type std::__invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf209be) BespokeSynth#15 std::_Function_handler<void (), juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf209be) BespokeSynth#16 std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf218c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#17 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182:13 (BespokeSynth+0xf218c9) BespokeSynth#18 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342:26 (BespokeSynth+0xf15ab7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#19 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109:19 (BespokeSynth+0xf1473d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262:40 (BespokeSynth+0xf1473d) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240:16 (BespokeSynth+0xf14660) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134:1 (BespokeSynth+0x66d0da) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) Location is heap block of size 1584 at 0x7b6c00000e00 allocated by main thread: #0 operator new(unsigned long) <null> (BespokeSynth+0x47ef66) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 Amplifier::Create() /home/jn/dev/synth/bespoke/Source/Amplifier.h:40:46 (BespokeSynth+0xa8f6b9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 ModuleFactory::MakeModule(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) /home/jn/dev/synth/bespoke/Source/ModuleFactory.cpp:522:17 (BespokeSynth+0xa8b5cd) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 ModularSynth::CreateModule(ofxJSONElement const&) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2524:37 (BespokeSynth+0x6bf7b8) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 ModuleContainer::LoadModules(ofxJSONElement const&) /home/jn/dev/synth/bespoke/Source/ModuleContainer.cpp:509:52 (BespokeSynth+0xa7cbb2) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 ModularSynth::LoadLayout(ofxJSONElement) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2478:21 (BespokeSynth+0x6bec6b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #6 ModularSynth::LoadLayoutFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2409:4 (BespokeSynth+0x6b00dc) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 ModularSynth::Poll() /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:350:13 (BespokeSynth+0x6aeea4) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:127:14 (BespokeSynth+0x677771) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #9 non-virtual thunk to MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp (BespokeSynth+0x677fd0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115:24 (BespokeSynth+0xf2426e) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181:27 (BespokeSynth+0xf2404b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42:62 (BespokeSynth+0xf270d7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#13 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf270d7) BespokeSynth#14 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf26fb0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#15 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)>::_M_invoke(std::_Any_data const&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf26fb0) BespokeSynth#16 std::function<void (int)>::operator()(int) const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf209be) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#17 juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3::operator()() const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359:80 (BespokeSynth+0xf209be) BespokeSynth#18 void std::__invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(std::__invoke_other, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf209be) BespokeSynth#19 std::enable_if<is_invocable_r_v<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>, void>::type std::__invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf209be) BespokeSynth#20 std::_Function_handler<void (), juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf209be) BespokeSynth#21 std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf218c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#22 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182:13 (BespokeSynth+0xf218c9) BespokeSynth#23 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342:26 (BespokeSynth+0xf15ab7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#24 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109:19 (BespokeSynth+0xf1473d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#25 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262:40 (BespokeSynth+0xf1473d) BespokeSynth#26 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240:16 (BespokeSynth+0xf14660) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#27 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134:1 (BespokeSynth+0x66d0da) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) Mutex M0 (0x7b8000056ce0) created at: #0 pthread_mutex_lock <null> (BespokeSynth+0x41cb4a) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 __gthread_mutex_lock(pthread_mutex_t*) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749:12 (BespokeSynth+0x6772a5) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 __gthread_recursive_mutex_lock(pthread_mutex_t*) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811:10 (BespokeSynth+0x6772a5) #3 std::recursive_mutex::lock() /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/mutex:108:17 (BespokeSynth+0x6772a5) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226:22 (BespokeSynth+0x6772a5) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:343:14 (BespokeSynth+0x6772a5) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61:5 (BespokeSynth+0x14c8c72) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 non-virtual thunk to juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp (BespokeSynth+0x14c8c72) #8 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326:31 (BespokeSynth+0x14e1113) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #9 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583:19 (BespokeSynth+0x14df030) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 non-virtual thunk to juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp (BespokeSynth+0x14df19d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384:27 (BespokeSynth+0xe2e78b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36:24 (BespokeSynth+0xeaedd9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#13 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96:13 (BespokeSynth+0xe2a2c6) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#14 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118:38 (BespokeSynth+0xe6c3c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#15 juce::threadEntryProc(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865:9 (BespokeSynth+0xe6c3c9) Thread T3 'Pool' (tid=795985, running) created by main thread at: #0 pthread_create <null> (BespokeSynth+0x3fefbd) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919:9 (BespokeSynth+0xe2a915) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130:9 (BespokeSynth+0xe2a7e6) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117:12 (BespokeSynth+0xe2c21f) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97:5 (BespokeSynth+0xe2bf05) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:1065:34 (BespokeSynth+0x14e2312) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163:28 (BespokeSynth+0x14e2312) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039:26 (BespokeSynth+0x14dcf04) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016:9 (BespokeSynth+0x14dcf04) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952:17 (BespokeSynth+0x14dd59f) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120:13 (BespokeSynth+0x11b2127) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::Component::sendVisibilityChangeMessage()::$_6::operator()(juce::ComponentListener&) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631:84 (BespokeSynth+0x1162ade) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 void juce::ListenerList<juce::ComponentListener, juce::Array<juce::ComponentListener*, juce::DummyCriticalSection, 0> >::callChecked<juce::Component::sendVisibilityChangeMessage()::$_6, juce::Component::BailOutChecker>(juce::Component::BailOutChecker const&, juce::Component::sendVisibilityChangeMessage()::$_6&&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170:13 (BespokeSynth+0x1162ade) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631:28 (BespokeSynth+0x1162ade) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609:13 (BespokeSynth+0x1162446) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105:10 (BespokeSynth+0x66dac0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:1065:34 (BespokeSynth+0x66d45a) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50:20 (BespokeSynth+0x66d45a) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297:5 (BespokeSynth+0xf149a8) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92:30 (BespokeSynth+0x12842e9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256:16 (BespokeSynth+0xf146f2) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240:16 (BespokeSynth+0xf14660) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134:1 (BespokeSynth+0x66d0da) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/IClickable.cpp:74:26 in IClickable::NotifyMouseMoved(float, float) ==================
Rejected approach: Introducing a ILockable class that contains the mutex variable. This would result in diamond-shaped inheritance graphs sooner or later, which can be resolved by declaring the inheritance as virtual, but that would probably result in slower code than necessary. ================== WARNING: ThreadSanitizer: data race (pid=795426) Read of size 4 at 0x7b6c00000e88 by thread T3 (mutexes: write M0): #0 IClickable::NotifyMouseMoved(float, float) /home/jn/dev/synth/bespoke/Source/IClickable.cpp:74:26 (BespokeSynth+0x60c873) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 ModuleContainer::MouseMoved(float, float) /home/jn/dev/synth/bespoke/Source/ModuleContainer.cpp:182:20 (BespokeSynth+0xa7a6c4) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 ModularSynth::MouseMoved(int, int) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:1288:24 (BespokeSynth+0x6b6d50) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:347:14 (BespokeSynth+0x6772f0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61:5 (BespokeSynth+0x14c8c72) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 non-virtual thunk to juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp (BespokeSynth+0x14c8c72) #6 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326:31 (BespokeSynth+0x14e1113) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583:19 (BespokeSynth+0x14df030) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 non-virtual thunk to juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp (BespokeSynth+0x14df19d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384:27 (BespokeSynth+0xe2e78b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36:24 (BespokeSynth+0xeaedd9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96:13 (BespokeSynth+0xe2a2c6) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118:38 (BespokeSynth+0xe6c3c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#13 juce::threadEntryProc(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865:9 (BespokeSynth+0xe6c3c9) Previous write of size 4 at 0x7b6c00000e88 by main thread: #0 IClickable::SetPosition(float, float) /home/jn/dev/synth/bespoke/Source/IClickable.h:44:10 (BespokeSynth+0x6b0333) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 ModularSynth::LoadLayoutFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2421:19 (BespokeSynth+0x6b0333) #2 ModularSynth::Poll() /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:350:13 (BespokeSynth+0x6aeea4) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:127:14 (BespokeSynth+0x677771) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 non-virtual thunk to MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp (BespokeSynth+0x677fd0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115:24 (BespokeSynth+0xf2426e) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #6 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181:27 (BespokeSynth+0xf2404b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42:62 (BespokeSynth+0xf270d7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf270d7) #9 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf26fb0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)>::_M_invoke(std::_Any_data const&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf26fb0) BespokeSynth#11 std::function<void (int)>::operator()(int) const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf209be) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3::operator()() const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359:80 (BespokeSynth+0xf209be) BespokeSynth#13 void std::__invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(std::__invoke_other, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf209be) BespokeSynth#14 std::enable_if<is_invocable_r_v<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>, void>::type std::__invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf209be) BespokeSynth#15 std::_Function_handler<void (), juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf209be) BespokeSynth#16 std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf218c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#17 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182:13 (BespokeSynth+0xf218c9) BespokeSynth#18 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342:26 (BespokeSynth+0xf15ab7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#19 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109:19 (BespokeSynth+0xf1473d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262:40 (BespokeSynth+0xf1473d) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240:16 (BespokeSynth+0xf14660) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134:1 (BespokeSynth+0x66d0da) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) Location is heap block of size 1584 at 0x7b6c00000e00 allocated by main thread: #0 operator new(unsigned long) <null> (BespokeSynth+0x47ef66) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 Amplifier::Create() /home/jn/dev/synth/bespoke/Source/Amplifier.h:40:46 (BespokeSynth+0xa8f6b9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 ModuleFactory::MakeModule(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) /home/jn/dev/synth/bespoke/Source/ModuleFactory.cpp:522:17 (BespokeSynth+0xa8b5cd) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 ModularSynth::CreateModule(ofxJSONElement const&) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2524:37 (BespokeSynth+0x6bf7b8) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 ModuleContainer::LoadModules(ofxJSONElement const&) /home/jn/dev/synth/bespoke/Source/ModuleContainer.cpp:509:52 (BespokeSynth+0xa7cbb2) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 ModularSynth::LoadLayout(ofxJSONElement) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2478:21 (BespokeSynth+0x6bec6b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #6 ModularSynth::LoadLayoutFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2409:4 (BespokeSynth+0x6b00dc) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 ModularSynth::Poll() /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:350:13 (BespokeSynth+0x6aeea4) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:127:14 (BespokeSynth+0x677771) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #9 non-virtual thunk to MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp (BespokeSynth+0x677fd0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115:24 (BespokeSynth+0xf2426e) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181:27 (BespokeSynth+0xf2404b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42:62 (BespokeSynth+0xf270d7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#13 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf270d7) BespokeSynth#14 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf26fb0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#15 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)>::_M_invoke(std::_Any_data const&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf26fb0) BespokeSynth#16 std::function<void (int)>::operator()(int) const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf209be) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#17 juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3::operator()() const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359:80 (BespokeSynth+0xf209be) BespokeSynth#18 void std::__invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(std::__invoke_other, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf209be) BespokeSynth#19 std::enable_if<is_invocable_r_v<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>, void>::type std::__invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf209be) BespokeSynth#20 std::_Function_handler<void (), juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf209be) BespokeSynth#21 std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf218c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#22 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182:13 (BespokeSynth+0xf218c9) BespokeSynth#23 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342:26 (BespokeSynth+0xf15ab7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#24 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109:19 (BespokeSynth+0xf1473d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#25 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262:40 (BespokeSynth+0xf1473d) BespokeSynth#26 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240:16 (BespokeSynth+0xf14660) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#27 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134:1 (BespokeSynth+0x66d0da) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) Mutex M0 (0x7b8000056ce0) created at: #0 pthread_mutex_lock <null> (BespokeSynth+0x41cb4a) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 __gthread_mutex_lock(pthread_mutex_t*) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749:12 (BespokeSynth+0x6772a5) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 __gthread_recursive_mutex_lock(pthread_mutex_t*) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811:10 (BespokeSynth+0x6772a5) #3 std::recursive_mutex::lock() /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/mutex:108:17 (BespokeSynth+0x6772a5) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226:22 (BespokeSynth+0x6772a5) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:343:14 (BespokeSynth+0x6772a5) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61:5 (BespokeSynth+0x14c8c72) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 non-virtual thunk to juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp (BespokeSynth+0x14c8c72) #8 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326:31 (BespokeSynth+0x14e1113) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #9 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583:19 (BespokeSynth+0x14df030) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 non-virtual thunk to juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp (BespokeSynth+0x14df19d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384:27 (BespokeSynth+0xe2e78b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36:24 (BespokeSynth+0xeaedd9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#13 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96:13 (BespokeSynth+0xe2a2c6) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#14 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118:38 (BespokeSynth+0xe6c3c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#15 juce::threadEntryProc(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865:9 (BespokeSynth+0xe6c3c9) Thread T3 'Pool' (tid=795985, running) created by main thread at: #0 pthread_create <null> (BespokeSynth+0x3fefbd) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919:9 (BespokeSynth+0xe2a915) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130:9 (BespokeSynth+0xe2a7e6) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117:12 (BespokeSynth+0xe2c21f) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97:5 (BespokeSynth+0xe2bf05) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:1065:34 (BespokeSynth+0x14e2312) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163:28 (BespokeSynth+0x14e2312) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039:26 (BespokeSynth+0x14dcf04) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016:9 (BespokeSynth+0x14dcf04) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952:17 (BespokeSynth+0x14dd59f) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120:13 (BespokeSynth+0x11b2127) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::Component::sendVisibilityChangeMessage()::$_6::operator()(juce::ComponentListener&) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631:84 (BespokeSynth+0x1162ade) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 void juce::ListenerList<juce::ComponentListener, juce::Array<juce::ComponentListener*, juce::DummyCriticalSection, 0> >::callChecked<juce::Component::sendVisibilityChangeMessage()::$_6, juce::Component::BailOutChecker>(juce::Component::BailOutChecker const&, juce::Component::sendVisibilityChangeMessage()::$_6&&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170:13 (BespokeSynth+0x1162ade) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631:28 (BespokeSynth+0x1162ade) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609:13 (BespokeSynth+0x1162446) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105:10 (BespokeSynth+0x66dac0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:1065:34 (BespokeSynth+0x66d45a) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50:20 (BespokeSynth+0x66d45a) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297:5 (BespokeSynth+0xf149a8) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92:30 (BespokeSynth+0x12842e9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256:16 (BespokeSynth+0xf146f2) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240:16 (BespokeSynth+0xf14660) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134:1 (BespokeSynth+0x66d0da) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/IClickable.cpp:74:26 in IClickable::NotifyMouseMoved(float, float) ==================
Rejected approach: Introducing a ILockable class that contains the mutex variable. This would result in diamond-shaped inheritance graphs sooner or later, which can be resolved by declaring the inheritance as virtual, but that would probably result in slower code than necessary. ================== WARNING: ThreadSanitizer: data race (pid=795426) Read of size 4 at 0x7b6c00000e88 by thread T3 (mutexes: write M0): #0 IClickable::NotifyMouseMoved(float, float) /home/jn/dev/synth/bespoke/Source/IClickable.cpp:74:26 (BespokeSynth+0x60c873) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 ModuleContainer::MouseMoved(float, float) /home/jn/dev/synth/bespoke/Source/ModuleContainer.cpp:182:20 (BespokeSynth+0xa7a6c4) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 ModularSynth::MouseMoved(int, int) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:1288:24 (BespokeSynth+0x6b6d50) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:347:14 (BespokeSynth+0x6772f0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61:5 (BespokeSynth+0x14c8c72) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 non-virtual thunk to juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp (BespokeSynth+0x14c8c72) #6 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326:31 (BespokeSynth+0x14e1113) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583:19 (BespokeSynth+0x14df030) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 non-virtual thunk to juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp (BespokeSynth+0x14df19d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #9 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384:27 (BespokeSynth+0xe2e78b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36:24 (BespokeSynth+0xeaedd9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96:13 (BespokeSynth+0xe2a2c6) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118:38 (BespokeSynth+0xe6c3c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#13 juce::threadEntryProc(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865:9 (BespokeSynth+0xe6c3c9) Previous write of size 4 at 0x7b6c00000e88 by main thread: #0 IClickable::SetPosition(float, float) /home/jn/dev/synth/bespoke/Source/IClickable.h:44:10 (BespokeSynth+0x6b0333) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 ModularSynth::LoadLayoutFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2421:19 (BespokeSynth+0x6b0333) #2 ModularSynth::Poll() /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:350:13 (BespokeSynth+0x6aeea4) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:127:14 (BespokeSynth+0x677771) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 non-virtual thunk to MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp (BespokeSynth+0x677fd0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115:24 (BespokeSynth+0xf2426e) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #6 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181:27 (BespokeSynth+0xf2404b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42:62 (BespokeSynth+0xf270d7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf270d7) #9 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf26fb0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)>::_M_invoke(std::_Any_data const&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf26fb0) BespokeSynth#11 std::function<void (int)>::operator()(int) const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf209be) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3::operator()() const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359:80 (BespokeSynth+0xf209be) BespokeSynth#13 void std::__invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(std::__invoke_other, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf209be) BespokeSynth#14 std::enable_if<is_invocable_r_v<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>, void>::type std::__invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf209be) BespokeSynth#15 std::_Function_handler<void (), juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf209be) BespokeSynth#16 std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf218c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#17 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182:13 (BespokeSynth+0xf218c9) BespokeSynth#18 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342:26 (BespokeSynth+0xf15ab7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#19 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109:19 (BespokeSynth+0xf1473d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262:40 (BespokeSynth+0xf1473d) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240:16 (BespokeSynth+0xf14660) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134:1 (BespokeSynth+0x66d0da) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) Location is heap block of size 1584 at 0x7b6c00000e00 allocated by main thread: #0 operator new(unsigned long) <null> (BespokeSynth+0x47ef66) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 Amplifier::Create() /home/jn/dev/synth/bespoke/Source/Amplifier.h:40:46 (BespokeSynth+0xa8f6b9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 ModuleFactory::MakeModule(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) /home/jn/dev/synth/bespoke/Source/ModuleFactory.cpp:522:17 (BespokeSynth+0xa8b5cd) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 ModularSynth::CreateModule(ofxJSONElement const&) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2524:37 (BespokeSynth+0x6bf7b8) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 ModuleContainer::LoadModules(ofxJSONElement const&) /home/jn/dev/synth/bespoke/Source/ModuleContainer.cpp:509:52 (BespokeSynth+0xa7cbb2) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 ModularSynth::LoadLayout(ofxJSONElement) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2478:21 (BespokeSynth+0x6bec6b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #6 ModularSynth::LoadLayoutFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:2409:4 (BespokeSynth+0x6b00dc) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 ModularSynth::Poll() /home/jn/dev/synth/bespoke/Source/ModularSynth.cpp:350:13 (BespokeSynth+0x6aeea4) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:127:14 (BespokeSynth+0x677771) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #9 non-virtual thunk to MainContentComponent::timerCallback() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp (BespokeSynth+0x677fd0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 juce::Timer::TimerThread::callTimers() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:115:24 (BespokeSynth+0xf2426e) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::Timer::TimerThread::CallTimersMessage::messageCallback() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/timers/juce_Timer.cpp:181:27 (BespokeSynth+0xf2404b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)::operator()(int) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:42:62 (BespokeSynth+0xf270d7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#13 void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf270d7) BespokeSynth#14 std::enable_if<is_invocable_r_v<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int>(juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf26fb0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#15 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::'lambda'(int)>::_M_invoke(std::_Any_data const&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf26fb0) BespokeSynth#16 std::function<void (int)>::operator()(int) const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf209be) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#17 juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3::operator()() const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:359:80 (BespokeSynth+0xf209be) BespokeSynth#18 void std::__invoke_impl<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(std::__invoke_other, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14 (BespokeSynth+0xf209be) BespokeSynth#19 std::enable_if<is_invocable_r_v<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>, void>::type std::__invoke_r<void, juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&>(juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2 (BespokeSynth+0xf209be) BespokeSynth#20 std::_Function_handler<void (), juce::LinuxEventLoop::registerFdCallback(int, std::function<void (int)>, short)::$_3>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9 (BespokeSynth+0xf209be) BespokeSynth#21 std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9 (BespokeSynth+0xf218c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#22 juce::InternalRunLoop::dispatchPendingEvents() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:182:13 (BespokeSynth+0xf218c9) BespokeSynth#23 juce::dispatchNextMessageOnSystemQueue(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:342:26 (BespokeSynth+0xf15ab7) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#24 juce::MessageManager::runDispatchLoop() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_MessageManager.cpp:109:19 (BespokeSynth+0xf1473d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#25 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:262:40 (BespokeSynth+0xf1473d) BespokeSynth#26 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240:16 (BespokeSynth+0xf14660) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#27 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134:1 (BespokeSynth+0x66d0da) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) Mutex M0 (0x7b8000056ce0) created at: #0 pthread_mutex_lock <null> (BespokeSynth+0x41cb4a) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 __gthread_mutex_lock(pthread_mutex_t*) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:749:12 (BespokeSynth+0x6772a5) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 __gthread_recursive_mutex_lock(pthread_mutex_t*) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12/bits/gthr-default.h:811:10 (BespokeSynth+0x6772a5) #3 std::recursive_mutex::lock() /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/mutex:108:17 (BespokeSynth+0x6772a5) #4 ModularSynth::LockRender(bool) /home/jn/dev/synth/bespoke/Source/ModularSynth.h:226:22 (BespokeSynth+0x6772a5) #5 MainContentComponent::render() /home/jn/dev/synth/bespoke/Source/MainComponent.cpp:343:14 (BespokeSynth+0x6772a5) #6 juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp:61:5 (BespokeSynth+0x14c8c72) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #7 non-virtual thunk to juce::OpenGLAppComponent::renderOpenGL() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp (BespokeSynth+0x14c8c72) #8 juce::OpenGLContext::CachedImage::renderFrame() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:326:31 (BespokeSynth+0x14e1113) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #9 juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:583:19 (BespokeSynth+0x14df030) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 non-virtual thunk to juce::OpenGLContext::CachedImage::runJob() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp (BespokeSynth+0x14df19d) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:384:27 (BespokeSynth+0xe2e78b) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 juce::ThreadPool::ThreadPoolThread::run() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:36:24 (BespokeSynth+0xeaedd9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#13 juce::Thread::threadEntryPoint() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:96:13 (BespokeSynth+0xe2a2c6) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#14 juce::juce_threadEntryPoint(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:118:38 (BespokeSynth+0xe6c3c9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#15 juce::threadEntryProc(void*) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:865:9 (BespokeSynth+0xe6c3c9) Thread T3 'Pool' (tid=795985, running) created by main thread at: #0 pthread_create <null> (BespokeSynth+0x3fefbd) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #1 juce::Thread::launchThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/native/juce_posix_SharedCode.h:919:9 (BespokeSynth+0xe2a915) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #2 juce::Thread::startThread() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_Thread.cpp:130:9 (BespokeSynth+0xe2a7e6) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #3 juce::ThreadPool::createThreads(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:117:12 (BespokeSynth+0xe2c21f) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #4 juce::ThreadPool::ThreadPool(int, unsigned long) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/threads/juce_ThreadPool.cpp:97:5 (BespokeSynth+0xe2bf05) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #5 std::__detail::_MakeUniq<juce::ThreadPool>::__single_object std::make_unique<juce::ThreadPool, int>(int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:1065:34 (BespokeSynth+0x14e2312) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #6 juce::OpenGLContext::CachedImage::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:163:28 (BespokeSynth+0x14e2312) #7 juce::OpenGLContext::Attachment::start() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1039:26 (BespokeSynth+0x14dcf04) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) #8 juce::OpenGLContext::Attachment::attach() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:1016:9 (BespokeSynth+0x14dcf04) #9 juce::OpenGLContext::Attachment::componentVisibilityChanged() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:952:17 (BespokeSynth+0x14dd59f) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#10 juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp:120:13 (BespokeSynth+0x11b2127) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#11 juce::Component::sendVisibilityChangeMessage()::$_6::operator()(juce::ComponentListener&) const /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631:84 (BespokeSynth+0x1162ade) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#12 void juce::ListenerList<juce::ComponentListener, juce::Array<juce::ComponentListener*, juce::DummyCriticalSection, 0> >::callChecked<juce::Component::sendVisibilityChangeMessage()::$_6, juce::Component::BailOutChecker>(juce::Component::BailOutChecker const&, juce::Component::sendVisibilityChangeMessage()::$_6&&) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_core/containers/juce_ListenerList.h:170:13 (BespokeSynth+0x1162ade) BespokeSynth#13 juce::Component::sendVisibilityChangeMessage() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:631:28 (BespokeSynth+0x1162ade) BespokeSynth#14 juce::Component::setVisible(bool) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/components/juce_Component.cpp:609:13 (BespokeSynth+0x1162446) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#15 BespokeApplication::MainWindow::MainWindow(juce::String) /home/jn/dev/synth/bespoke/Source/Main.cpp:105:10 (BespokeSynth+0x66dac0) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#16 std::__detail::_MakeUniq<BespokeApplication::MainWindow>::__single_object std::make_unique<BespokeApplication::MainWindow, char const (&) [14]>(char const (&) [14]) /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:1065:34 (BespokeSynth+0x66d45a) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#17 BespokeApplication::initialise(juce::String const&) /home/jn/dev/synth/bespoke/Source/Main.cpp:50:20 (BespokeSynth+0x66d45a) BespokeSynth#18 juce::JUCEApplicationBase::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:297:5 (BespokeSynth+0xf149a8) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#19 juce::JUCEApplication::initialiseApp() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:92:30 (BespokeSynth+0x12842e9) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#20 juce::JUCEApplicationBase::main() /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256:16 (BespokeSynth+0xf146f2) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#21 juce::JUCEApplicationBase::main(int, char const**) /home/jn/dev/synth/bespoke/libs/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:240:16 (BespokeSynth+0xf14660) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) BespokeSynth#22 main /home/jn/dev/synth/bespoke/Source/Main.cpp:134:1 (BespokeSynth+0x66d0da) (BuildId: bf42b258c9ff339def937105d642b7193dbc302b) SUMMARY: ThreadSanitizer: data race /home/jn/dev/synth/bespoke/Source/IClickable.cpp:74:26 in IClickable::NotifyMouseMoved(float, float) ==================
When opening a state (
.bsk
file), Bespoke crashes or almost crashes. Sometimes there’s also a humming noise on the audio signal.OS: macOS 10.15.6
The text was updated successfully, but these errors were encountered: