Kaydet (Commit) 42314253 authored tarafından Michael Stahl's avatar Michael Stahl

add a RAII class that tries to acquire the SolarMutex and releases it

Motivated by ScCompiler::IsMacro() which has an error return that does
not release the SolarMutex.

Change-Id: I064219bb3c0d68839a133101491d5f8828a26c7a
üst 93e7ffbd
...@@ -1659,6 +1659,53 @@ protected: ...@@ -1659,6 +1659,53 @@ protected:
comphelper::SolarMutex& m_solarMutex; comphelper::SolarMutex& m_solarMutex;
}; };
namespace vcl
{
/** guard class that uses tryToAcquire() and has isAcquired() to check
*/
class SolarMutexTryAndBuyGuard
: private boost::noncopyable
{
private:
bool m_isAcquired;
#if OSL_DEBUG_LEVEL > 0
bool m_isChecked;
#endif
comphelper::SolarMutex& m_rSolarMutex;
public:
SolarMutexTryAndBuyGuard()
: m_isAcquired(false)
#if OSL_DEBUG_LEVEL > 0
, m_isChecked(false)
#endif
, m_rSolarMutex(Application::GetSolarMutex())
{
m_isAcquired = m_rSolarMutex.tryToAcquire();
}
~SolarMutexTryAndBuyGuard()
{
#if OSL_DEBUG_LEVEL > 0
assert(m_isChecked);
#endif
if (m_isAcquired)
m_rSolarMutex.release();
}
bool isAcquired()
{
#if OSL_DEBUG_LEVEL > 0
m_isChecked = true;
#endif
return m_isAcquired;
}
};
} // namespace vcl
/** /**
A helper class that calls Application::ReleaseSolarMutex() in its constructor A helper class that calls Application::ReleaseSolarMutex() in its constructor
......
...@@ -877,13 +877,12 @@ void ScDocument::RemoveUnoObject( SfxListener& rObject ) ...@@ -877,13 +877,12 @@ void ScDocument::RemoveUnoObject( SfxListener& rObject )
// This check is done after calling EndListening, so a later BroadcastUno call // This check is done after calling EndListening, so a later BroadcastUno call
// won't touch this object. // won't touch this object.
comphelper::SolarMutex& rSolarMutex = Application::GetSolarMutex(); vcl::SolarMutexTryAndBuyGuard g;
if ( rSolarMutex.tryToAcquire() ) if (g.isAcquired())
{ {
// BroadcastUno is always called with the SolarMutex locked, so if it // BroadcastUno is always called with the SolarMutex locked, so if it
// can be acquired, this is within the same thread (should not happen) // can be acquired, this is within the same thread (should not happen)
OSL_FAIL( "RemoveUnoObject called from BroadcastUno" ); OSL_FAIL( "RemoveUnoObject called from BroadcastUno" );
rSolarMutex.release();
} }
else else
{ {
......
...@@ -2819,8 +2819,8 @@ bool ScCompiler::IsMacro( const OUString& rName ) ...@@ -2819,8 +2819,8 @@ bool ScCompiler::IsMacro( const OUString& rName )
// formulas are compiled from a threaded import may result in a deadlock. // formulas are compiled from a threaded import may result in a deadlock.
// Check first if we actually could acquire it and if not bail out. // Check first if we actually could acquire it and if not bail out.
/* FIXME: yes, but how ... */ /* FIXME: yes, but how ... */
comphelper::SolarMutex& rSolarMutex = Application::GetSolarMutex(); vcl::SolarMutexTryAndBuyGuard g;
if (!rSolarMutex.tryToAcquire()) if (!g.isAcquired())
{ {
SAL_WARN( "sc.core", "ScCompiler::IsMacro - SolarMutex would deadlock, not obtaining Basic"); SAL_WARN( "sc.core", "ScCompiler::IsMacro - SolarMutex would deadlock, not obtaining Basic");
return false; // bad luck return false; // bad luck
...@@ -2854,7 +2854,6 @@ bool ScCompiler::IsMacro( const OUString& rName ) ...@@ -2854,7 +2854,6 @@ bool ScCompiler::IsMacro( const OUString& rName )
SbxMethod* pMeth = (SbxMethod*) pObj->Find( aName, SbxCLASS_METHOD ); SbxMethod* pMeth = (SbxMethod*) pObj->Find( aName, SbxCLASS_METHOD );
if( !pMeth ) if( !pMeth )
{ {
rSolarMutex.release();
return false; return false;
} }
// It really should be a BASIC function! // It really should be a BASIC function!
...@@ -2862,12 +2861,10 @@ bool ScCompiler::IsMacro( const OUString& rName ) ...@@ -2862,12 +2861,10 @@ bool ScCompiler::IsMacro( const OUString& rName )
|| ( pMeth->IsFixed() && pMeth->GetType() == SbxEMPTY ) || ( pMeth->IsFixed() && pMeth->GetType() == SbxEMPTY )
|| !pMeth->ISA(SbMethod) ) || !pMeth->ISA(SbMethod) )
{ {
rSolarMutex.release();
return false; return false;
} }
maRawToken.SetExternal( aName.getStr() ); maRawToken.SetExternal( aName.getStr() );
maRawToken.eOp = ocMacro; maRawToken.eOp = ocMacro;
rSolarMutex.release();
return true; return true;
#endif #endif
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment