Rendering to two graphic context on two threads deadlocks application

Hi there

I have an application that needs to prepare a bitmap on a worker thread, while main thread is updating several controls. From time to time, the system gets stuck with both threads waiting for a Glyph synch object. Please see the attached stack frame for both process.

Maybe is required any action before starting a render operation in background?

My juce version is JUCE-3.0.4

I left this message in Windows forum, but eventually may happen in more systems.

Thanks for your support.
Juan


Not Flagged    >    0x00002350    0x00    Worker Thread    Juce Message Thread    JuanApp.exe!juce::WaitableEvent::wait    Normal
     ntdll.dll!_ZwWaitForSingleObject@12()    Unknown
     ntdll.dll!_ZwWaitForSingleObject@12()    Unknown
>    JuanApp.exe!juce::WaitableEvent::wait(int timeOutMs) Line 91    C++
     JuanApp.exe!juce::ReadWriteLock::enterWrite() Line 123    C++
     JuanApp.exe!juce::ScopedWriteLock::ScopedWriteLock(const juce::ReadWriteLock & lock) Line 70    C++
     JuanApp.exe!juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>,juce::RenderingHelpers::SoftwareRendererSavedState>::drawGlyph(juce::RenderingHelpers::SoftwareRendererSavedState & target, const juce::Font & font, const int glyphNumber, juce::Point<float> pos) Line 187    C++
     JuanApp.exe!juce::RenderingHelpers::SoftwareRendererSavedState::drawGlyph(int glyphNumber, const juce::AffineTransform & trans) Line 2476    C++
     JuanApp.exe!juce::RenderingHelpers::StackBasedLowLevelGraphicsContext<juce::RenderingHelpers::SoftwareRendererSavedState>::drawGlyph(int glyphNumber, const juce::AffineTransform & t) Line 2648    C++
     JuanApp.exe!juce::drawGlyphWithFont(const juce::Graphics & g, int glyph, const juce::Font & font, const juce::AffineTransform & t) Line 62    C++
     JuanApp.exe!juce::PositionedGlyph::draw(const juce::Graphics & g) Line 67    C++
     JuanApp.exe!juce::GlyphArrangement::draw(const juce::Graphics & g) Line 731    C++
     JuanApp.exe!juce::Graphics::drawFittedText(const juce::String & text, const juce::Rectangle<int> & area, juce::Justification justification, int maximumNumberOfLines, float minimumHorizontalScale) Line 328    C++
     JuanApp.exe!juce::Graphics::drawFittedText(const juce::String & text, int x, int y, int width, int height, juce::Justification justification, int maximumNumberOfLines, float minimumHorizontalScale) Line 337    C++
     JuanApp.exe!juce::LookAndFeel_V2::drawMenuBarItem(juce::Graphics & g, int width, int height, int itemIndex, const juce::String & itemText, bool isMouseOverItem, bool isMenuOpen, bool __formal, juce::MenuBarComponent & menuBar) Line 1051    C++
     JuanApp.exe!juce::MenuBarComponent::paint(juce::Graphics & g) Line 95    C++
     JuanApp.exe!juce::Component::paintComponentAndChildren(juce::Graphics & g) Line 1979    C++
     JuanApp.exe!juce::Component::paintEntireComponent(juce::Graphics & g, bool ignoreAlphaLevel) Line 2076    C++
     JuanApp.exe!juce::Component::paintWithinParentContext(juce::Graphics & g) Line 1962    C++
     JuanApp.exe!juce::Component::paintComponentAndChildren(juce::Graphics & g) Line 2025    C++
     JuanApp.exe!juce::Component::paintEntireComponent(juce::Graphics & g, bool ignoreAlphaLevel) Line 2076    C++
     JuanApp.exe!juce::ComponentPeer::handlePaint(juce::LowLevelGraphicsContext & contextToPaintTo) Line 163    C++
     JuanApp.exe!juce::HWNDComponentPeer::performPaint(HDC__ * dc, HRGN__ * rgn, int regionType, tagPAINTSTRUCT & paintStruct) Line 1583    C++
     JuanApp.exe!juce::HWNDComponentPeer::handlePaintMessage() Line 1478    C++
     JuanApp.exe!juce::HWNDComponentPeer::peerWindowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 2303    C++
     JuanApp.exe!juce::HWNDComponentPeer::windowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 2256    C++
     user32.dll!_InternalCallWinProc@20()    Unknown
     user32.dll!_UserCallWinProcCheckWow@32()    Unknown
     user32.dll!_DispatchClientMessage@24()    Unknown
     user32.dll!___fnDWORD@4()    Unknown
     ntdll.dll!_KiUserCallbackDispatcher@12()    Unknown
     user32.dll!_NtUserDispatchMessage@4()    Unknown
     user32.dll!_DispatchMessageWorker@8()    Unknown
     user32.dll!_DispatchMessageW@4()    Unknown
     JuanApp.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 138    C++
     JuanApp.exe!juce::MessageManager::runDispatchLoopUntil(int millisecondsToRunFor) Line 94    C++
     JuanApp.exe!juce::MessageManager::runDispatchLoop() Line 82    C++
     JuanApp.exe!juce::JUCEApplicationBase::main() Line 239    C++
     JuanApp.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 145    C++
     JuanApp.exe!__tmainCRTStartup() Line 238    C
     JuanApp.exe!WinMainCRTStartup() Line 164    C
     kernel32.dll!@BaseThreadInitThunk@12()    Unknown
     ntdll.dll!___RtlUserThreadStart@8()    Unknown
     ntdll.dll!__RtlUserThreadStart@8()    Unknown

    
    
Not Flagged    >    0x000021C4    0x00    Worker Thread    OSD Render Thread    JuanApp.exe!juce::WaitableEvent::wait    Idle
     ntdll.dll!_ZwWaitForSingleObject@12()    Unknown
     ntdll.dll!_ZwWaitForSingleObject@12()    Unknown
>    JuanApp.exe!juce::WaitableEvent::wait(int timeOutMs) Line 91    C++
     JuanApp.exe!juce::ReadWriteLock::enterWrite() Line 123    C++
     JuanApp.exe!juce::ScopedWriteLock::ScopedWriteLock(const juce::ReadWriteLock & lock) Line 70    C++
     JuanApp.exe!juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>,juce::RenderingHelpers::SoftwareRendererSavedState>::drawGlyph(juce::RenderingHelpers::SoftwareRendererSavedState & target, const juce::Font & font, const int glyphNumber, juce::Point<float> pos) Line 187    C++
     JuanApp.exe!juce::RenderingHelpers::SoftwareRendererSavedState::drawGlyph(int glyphNumber, const juce::AffineTransform & trans) Line 2476    C++
     JuanApp.exe!juce::RenderingHelpers::StackBasedLowLevelGraphicsContext<juce::RenderingHelpers::SoftwareRendererSavedState>::drawGlyph(int glyphNumber, const juce::AffineTransform & t) Line 2648    C++
     JuanApp.exe!juce::drawGlyphWithFont(const juce::Graphics & g, int glyph, const juce::Font & font, const juce::AffineTransform & t) Line 62    C++
     JuanApp.exe!juce::PositionedGlyph::draw(const juce::Graphics & g) Line 67    C++
     JuanApp.exe!juce::GlyphArrangement::draw(const juce::Graphics & g) Line 731    C++
     JuanApp.exe!juce::Graphics::drawText(const juce::String & text, const juce::Rectangle<float> & area, juce::Justification justificationType, bool useEllipsesIfTooBig) Line 297    C++
     JuanApp.exe!juce::Graphics::drawText(const juce::String & text, const juce::Rectangle<int> & area, juce::Justification justificationType, bool useEllipsesIfTooBig) Line 303    C++
     JuanApp.exe!juce::Graphics::drawText(const juce::String & text, int x, int y, int width, int height, juce::Justification justificationType, bool useEllipsesIfTooBig) Line 309    C++
     JuanApp.exe!OSD_Render::internalProcessPrintOrder(OSD_RenderOrder * pOrder) Line 228    C++
     JuanApp.exe!OSD_Render::run() Line 76    C++
     JuanApp.exe!juce::Thread::threadEntryPoint() Line 106    C++
     JuanApp.exe!juce::juce_threadEntryPoint(void * userData) Line 114    C++
     JuanApp.exe!juce::threadEntryProc(void * userData) Line 103    C++
     JuanApp.exe!_callthreadstartex() Line 354    C
     JuanApp.exe!_threadstartex(void * ptd) Line 337    C
     kernel32.dll!@BaseThreadInitThunk@12()    Unknown
     ntdll.dll!___RtlUserThreadStart@8()    Unknown
     ntdll.dll!__RtlUserThreadStart@8()    Unknown
   

 

Even sometimes the render operation fails, with a bad memory access,

juce_win32_Fonts.cpp line 431,
"                    if (curve->wType == TT_PRIM_LINE)" and the contains of the curve data structure are:
+        curve    0x06805250 {wType=??? cpfx=??? apfx=0x06805254 {{x={fract=??? value=??? } y={fract=??? value=??? } }} }    const tagTTPOLYCURVE *


Stack frames are:


Unhandled exception at 0x00C1F203 in JuanApp.exe: 0xC0000005: Access violation reading location 0x06805250.

Not Flagged    >    0x00000948    0x00    Worker Thread    OSD Render Thread    JuanApp.exe!juce::WindowsTypeface::getOutlineForGlyph    Idle

>    JuanApp.exe!juce::WindowsTypeface::getOutlineForGlyph(int glyphNumber, juce::Path & glyphPath) Line 431    C++
     JuanApp.exe!juce::Typeface::getEdgeTableForGlyph(int glyphNumber, const juce::AffineTransform & transform, float fontHeight) Line 123    C++
     JuanApp.exe!juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>::generate(const juce::Font & newFont, const int glyphNumber) Line 289    C++
     JuanApp.exe!juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>,juce::RenderingHelpers::SoftwareRendererSavedState>::drawGlyph(juce::RenderingHelpers::SoftwareRendererSavedState & target, const juce::Font & font, const int glyphNumber, juce::Point<float> pos) Line 205    C++
     JuanApp.exe!juce::RenderingHelpers::SoftwareRendererSavedState::drawGlyph(int glyphNumber, const juce::AffineTransform & trans) Line 2476    C++
     JuanApp.exe!juce::RenderingHelpers::StackBasedLowLevelGraphicsContext<juce::RenderingHelpers::SoftwareRendererSavedState>::drawGlyph(int glyphNumber, const juce::AffineTransform & t) Line 2648    C++
     JuanApp.exe!juce::drawGlyphWithFont(const juce::Graphics & g, int glyph, const juce::Font & font, const juce::AffineTransform & t) Line 62    C++
     JuanApp.exe!juce::PositionedGlyph::draw(const juce::Graphics & g) Line 67    C++
     JuanApp.exe!juce::GlyphArrangement::draw(const juce::Graphics & g) Line 731    C++
     JuanApp.exe!juce::Graphics::drawText(const juce::String & text, const juce::Rectangle<float> & area, juce::Justification justificationType, bool useEllipsesIfTooBig) Line 297    C++
     JuanApp.exe!juce::Graphics::drawText(const juce::String & text, const juce::Rectangle<int> & area, juce::Justification justificationType, bool useEllipsesIfTooBig) Line 303    C++
     JuanApp.exe!juce::Graphics::drawText(const juce::String & text, int x, int y, int width, int height, juce::Justification justificationType, bool useEllipsesIfTooBig) Line 309    C++
     JuanApp.exe!OSD_Render::internalProcessPrintOrder(OSD_RenderOrder * pOrder) Line 228    C++
     JuanApp.exe!OSD_Render::run() Line 76    C++
     JuanApp.exe!juce::Thread::threadEntryPoint() Line 106    C++
     JuanApp.exe!juce::juce_threadEntryPoint(void * userData) Line 114    C++
     JuanApp.exe!juce::threadEntryProc(void * userData) Line 103    C++
     JuanApp.exe!_callthreadstartex() Line 354    C
     JuanApp.exe!_threadstartex(void * ptd) Line 337    C
     kernel32.dll!@BaseThreadInitThunk@12()    Unknown
     ntdll.dll!___RtlUserThreadStart@8()    Unknown
     ntdll.dll!__RtlUserThreadStart@8()    Unknown

    
    
    
Not Flagged    >    0x000013D4    0x00    Worker Thread    Juce Message Thread    JuanApp.exe!juce::LookAndFeel_V2::drawDocumentWindowTitleBar    Normal
    >    JuanApp.exe!juce::LookAndFeel_V2::drawDocumentWindowTitleBar(juce::DocumentWindow & window, juce::Graphics & g, int w, int h, int titleSpaceX, int titleSpaceW, const juce::Image * icon, bool drawTitleTextOnLeft) Line 1669    C++
     JuanApp.exe!juce::DocumentWindow::paint(juce::Graphics & g) Line 225    C++
     JuanApp.exe!juce::Component::paintComponentAndChildren(juce::Graphics & g) Line 1979    C++
     JuanApp.exe!juce::Component::paintEntireComponent(juce::Graphics & g, bool ignoreAlphaLevel) Line 2076    C++
     JuanApp.exe!juce::ComponentPeer::handlePaint(juce::LowLevelGraphicsContext & contextToPaintTo) Line 163    C++
     JuanApp.exe!juce::HWNDComponentPeer::performPaint(HDC__ * dc, HRGN__ * rgn, int regionType, tagPAINTSTRUCT & paintStruct) Line 1583    C++
     JuanApp.exe!juce::HWNDComponentPeer::handlePaintMessage() Line 1478    C++
     JuanApp.exe!juce::HWNDComponentPeer::peerWindowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 2303    C++
     JuanApp.exe!juce::HWNDComponentPeer::windowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 2256    C++
     user32.dll!_InternalCallWinProc@20()    Unknown
     user32.dll!_UserCallWinProcCheckWow@32()    Unknown
     user32.dll!_DispatchClientMessage@24()    Unknown
     user32.dll!___fnDWORD@4()    Unknown
     ntdll.dll!_KiUserCallbackDispatcher@12()    Unknown
     user32.dll!_NtUserDispatchMessage@4()    Unknown
     user32.dll!_DispatchMessageWorker@8()    Unknown
     user32.dll!_DispatchMessageW@4()    Unknown
     JuanApp.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 138    C++
     JuanApp.exe!juce::MessageManager::runDispatchLoopUntil(int millisecondsToRunFor) Line 94    C++
     JuanApp.exe!juce::MessageManager::runDispatchLoop() Line 82    C++
     JuanApp.exe!juce::JUCEApplicationBase::main() Line 239    C++
     JuanApp.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 145    C++
     JuanApp.exe!__tmainCRTStartup() Line 238    C
     JuanApp.exe!WinMainCRTStartup() Line 164    C
     kernel32.dll!@BaseThreadInitThunk@12()    Unknown
     ntdll.dll!___RtlUserThreadStart@8()    Unknown
     ntdll.dll!__RtlUserThreadStart@8()    Unknown

 

I wrote some code to try to reproduce this, but even with many threads running, it all seemed to work just fine. And I can't see any obvious threading mistakes..

Perhaps you can give me a bit of sample code that shows the crash?