diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2017-11-08 19:01:10 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2017-11-09 08:10:39 +0100 |
commit | b5b78703b5d801c2a9a5e45126f8e87bf5ebd4b4 (patch) | |
tree | 971c68facd3df74a772ef809201469179013d045 /vcl/inc/osx | |
parent | 9fbe22e1d9b30c5c0087e84809c80b936c5c142f (diff) |
Avoid races when using OSX_RUNINMAIN_MEMBERS
...so that e.g. main thread in SalYieldMutex::doAcquire could reset
m_aInMainTHreadCondition and then block waiting on it only after another thread
had set it. (Saw such a deadlock in some 'make check' CppunitTest.)
Change-Id: I5c676956a2bec6bf8f94d7dbeee64f100db39bd3
Reviewed-on: https://gerrit.libreoffice.org/44501
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'vcl/inc/osx')
-rw-r--r-- | vcl/inc/osx/runinmain.hxx | 79 | ||||
-rw-r--r-- | vcl/inc/osx/salinst.h | 4 |
2 files changed, 54 insertions, 29 deletions
diff --git a/vcl/inc/osx/runinmain.hxx b/vcl/inc/osx/runinmain.hxx index a57b7908214d..8f8559dac5c8 100644 --- a/vcl/inc/osx/runinmain.hxx +++ b/vcl/inc/osx/runinmain.hxx @@ -57,8 +57,11 @@ union RuninmainResult }; #define OSX_RUNINMAIN_MEMBERS \ - osl::Condition m_aInMainCondition; \ - osl::Condition m_aResultCondition; \ + std::mutex m_runInMainMutex; \ + std::condition_variable m_aInMainCondition; \ + std::condition_variable m_aResultCondition; \ + bool m_wakeUpMain = false; \ + bool m_resultReady = false; \ RuninmainBlock m_aCodeBlock; \ RuninmainResult m_aResult; @@ -67,18 +70,24 @@ union RuninmainResult { \ DBG_TESTSOLARMUTEX(); \ SalYieldMutex *aMutex = static_cast<SalYieldMutex*>(instance->GetYieldMutex()); \ - assert( !aMutex->m_aCodeBlock ); \ - aMutex->m_aCodeBlock = Block_copy(^{ \ - command; \ - }); \ - aMutex->m_aResultCondition.reset(); \ + { \ + std::unique_lock<std::mutex> g(aMutex->m_runInMainMutex); \ + assert( !aMutex->m_aCodeBlock ); \ + aMutex->m_aCodeBlock = Block_copy(^{ \ + command; \ + }); \ + aMutex->m_wakeUpMain = true; \ + aMutex->m_aInMainCondition.notify_all(); \ + } \ dispatch_async(dispatch_get_main_queue(),^{ \ ImplNSAppPostEvent( AquaSalInstance::YieldWakeupEvent, NO ); \ }); \ - aMutex->m_aInMainCondition.set(); \ - osl::Condition::Result res = aMutex->m_aResultCondition.wait(); \ - (void) res; \ - assert(osl::Condition::Result::result_ok == res); \ + { \ + std::unique_lock<std::mutex> g(aMutex->m_runInMainMutex); \ + aMutex->m_aResultCondition.wait( \ + g, [&aMutex]() { return aMutex->m_resultReady; }); \ + aMutex->m_resultReady = false; \ + } \ return; \ } @@ -87,18 +96,24 @@ union RuninmainResult { \ DBG_TESTSOLARMUTEX(); \ SalYieldMutex *aMutex = static_cast<SalYieldMutex*>(instance->GetYieldMutex()); \ - assert( !aMutex->m_aCodeBlock ); \ - aMutex->m_aCodeBlock = Block_copy(^{ \ - aMutex->m_aResult.pointer = static_cast<void*>( command ); \ - }); \ - aMutex->m_aResultCondition.reset(); \ + { \ + std::unique_lock<std::mutex> g(aMutex->m_runInMainMutex); \ + assert( !aMutex->m_aCodeBlock ); \ + aMutex->m_aCodeBlock = Block_copy(^{ \ + aMutex->m_aResult.pointer = static_cast<void*>( command ); \ + }); \ + aMutex->m_wakeUpMain = true; \ + aMutex->m_aInMainCondition.notify_all(); \ + } \ dispatch_async(dispatch_get_main_queue(),^{ \ ImplNSAppPostEvent( AquaSalInstance::YieldWakeupEvent, NO ); \ }); \ - aMutex->m_aInMainCondition.set(); \ - osl::Condition::Result res = aMutex->m_aResultCondition.wait(); \ - (void) res; \ - assert(osl::Condition::Result::result_ok == res); \ + { \ + std::unique_lock<std::mutex> g(aMutex->m_runInMainMutex); \ + aMutex->m_aResultCondition.wait( \ + g, [&aMutex]() { return aMutex->m_resultReady; }); \ + aMutex->m_resultReady = false; \ + } \ return static_cast<type>( aMutex->m_aResult.pointer ); \ } @@ -107,18 +122,24 @@ union RuninmainResult { \ DBG_TESTSOLARMUTEX(); \ SalYieldMutex *aMutex = static_cast<SalYieldMutex*>(instance->GetYieldMutex()); \ - assert( !aMutex->m_aCodeBlock ); \ - aMutex->m_aCodeBlock = Block_copy(^{ \ - aMutex->m_aResult.member = command; \ - }); \ - aMutex->m_aResultCondition.reset(); \ + { \ + std::unique_lock<std::mutex> g(aMutex->m_runInMainMutex); \ + assert( !aMutex->m_aCodeBlock ); \ + aMutex->m_aCodeBlock = Block_copy(^{ \ + aMutex->m_aResult.member = command; \ + }); \ + aMutex->m_wakeUpMain = true; \ + aMutex->m_aInMainCondition.notify_all(); \ + } \ dispatch_async(dispatch_get_main_queue(),^{ \ ImplNSAppPostEvent( AquaSalInstance::YieldWakeupEvent, NO ); \ }); \ - aMutex->m_aInMainCondition.set(); \ - osl::Condition::Result res = aMutex->m_aResultCondition.wait(); \ - (void) res; \ - assert(osl::Condition::Result::result_ok == res); \ + { \ + std::unique_lock<std::mutex> g(aMutex->m_runInMainMutex); \ + aMutex->m_aResultCondition.wait( \ + g, [&aMutex]() { return aMutex->m_resultReady; }); \ + aMutex->m_resultReady = false; \ + } \ return std::move( aMutex->m_aResult.member ); \ } diff --git a/vcl/inc/osx/salinst.h b/vcl/inc/osx/salinst.h index 95dd4db26c24..f96eefaa8950 100644 --- a/vcl/inc/osx/salinst.h +++ b/vcl/inc/osx/salinst.h @@ -21,7 +21,11 @@ #ifndef INCLUDED_VCL_INC_OSX_SALINST_H #define INCLUDED_VCL_INC_OSX_SALINST_H +#include <sal/config.h> + +#include <condition_variable> #include <list> +#include <mutex> #include <comphelper/solarmutex.hxx> #include <osl/conditn.hxx> |