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:
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
......
......@@ -877,13 +877,12 @@ void ScDocument::RemoveUnoObject( SfxListener& rObject )
// This check is done after calling EndListening, so a later BroadcastUno call
// won't touch this object.
comphelper::SolarMutex& rSolarMutex = Application::GetSolarMutex();
if ( rSolarMutex.tryToAcquire() )
vcl::SolarMutexTryAndBuyGuard g;
if (g.isAcquired())
{
// BroadcastUno is always called with the SolarMutex locked, so if it
// can be acquired, this is within the same thread (should not happen)
OSL_FAIL( "RemoveUnoObject called from BroadcastUno" );
rSolarMutex.release();
}
else
{
......
......@@ -2819,8 +2819,8 @@ bool ScCompiler::IsMacro( const OUString& rName )
// 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.
/* FIXME: yes, but how ... */
comphelper::SolarMutex& rSolarMutex = Application::GetSolarMutex();
if (!rSolarMutex.tryToAcquire())
vcl::SolarMutexTryAndBuyGuard g;
if (!g.isAcquired())
{
SAL_WARN( "sc.core", "ScCompiler::IsMacro - SolarMutex would deadlock, not obtaining Basic");
return false; // bad luck
......@@ -2854,7 +2854,6 @@ bool ScCompiler::IsMacro( const OUString& rName )
SbxMethod* pMeth = (SbxMethod*) pObj->Find( aName, SbxCLASS_METHOD );
if( !pMeth )
{
rSolarMutex.release();
return false;
}
// It really should be a BASIC function!
......@@ -2862,12 +2861,10 @@ bool ScCompiler::IsMacro( const OUString& rName )
|| ( pMeth->IsFixed() && pMeth->GetType() == SbxEMPTY )
|| !pMeth->ISA(SbMethod) )
{
rSolarMutex.release();
return false;
}
maRawToken.SetExternal( aName.getStr() );
maRawToken.eOp = ocMacro;
rSolarMutex.release();
return true;
#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