summaryrefslogtreecommitdiff
path: root/vcl/inc/osx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2017-11-08 19:01:10 +0100
committerStephan Bergmann <sbergman@redhat.com>2017-11-09 08:10:39 +0100
commitb5b78703b5d801c2a9a5e45126f8e87bf5ebd4b4 (patch)
tree971c68facd3df74a772ef809201469179013d045 /vcl/inc/osx
parent9fbe22e1d9b30c5c0087e84809c80b936c5c142f (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.hxx79
-rw-r--r--vcl/inc/osx/salinst.h4
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>