diff options
Diffstat (limited to 'basic/source/runtime/basrdll.cxx')
-rw-r--r-- | basic/source/runtime/basrdll.cxx | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/basic/source/runtime/basrdll.cxx b/basic/source/runtime/basrdll.cxx index a3145f404979..9fd82145afd2 100644 --- a/basic/source/runtime/basrdll.cxx +++ b/basic/source/runtime/basrdll.cxx @@ -28,69 +28,80 @@ #include <sbxbase.hxx> #include <config_features.h> -struct BasicDLL::Impl +namespace +{ +struct BasicDLLImpl : public SvRefBase { bool bDebugMode; bool bBreakEnabled; std::unique_ptr<SbxAppData> xSbxAppData; - Impl() + BasicDLLImpl() : bDebugMode(false) , bBreakEnabled(true) , xSbxAppData(new SbxAppData) { } -}; - -namespace { -BasicDLL * BASIC_DLL; + static BasicDLLImpl* BASIC_DLL; + static osl::Mutex& getMutex() + { + static osl::Mutex aMutex; + return aMutex; + } +}; +BasicDLLImpl* BasicDLLImpl::BASIC_DLL = nullptr; } BasicDLL::BasicDLL() - : m_xImpl(new Impl) { - BASIC_DLL = this; + osl::MutexGuard aGuard(BasicDLLImpl::getMutex()); + if (!BasicDLLImpl::BASIC_DLL) + BasicDLLImpl::BASIC_DLL = new BasicDLLImpl; + m_xImpl = BasicDLLImpl::BASIC_DLL; } BasicDLL::~BasicDLL() { + osl::MutexGuard aGuard(BasicDLLImpl::getMutex()); + const bool bLastRef = m_xImpl->GetRefCount() == 1; + m_xImpl.clear(); + // only reset BASIC_DLL after the object had been destroyed + if (bLastRef) + BasicDLLImpl::BASIC_DLL = nullptr; } void BasicDLL::EnableBreak( bool bEnable ) { - BasicDLL* pThis = BASIC_DLL; - DBG_ASSERT( pThis, "BasicDLL::EnableBreak: No instance yet!" ); - if ( pThis ) + DBG_ASSERT( BasicDLLImpl::BASIC_DLL, "BasicDLL::EnableBreak: No instance yet!" ); + if (BasicDLLImpl::BASIC_DLL) { - pThis->m_xImpl->bBreakEnabled = bEnable; + BasicDLLImpl::BASIC_DLL->bBreakEnabled = bEnable; } } void BasicDLL::SetDebugMode( bool bDebugMode ) { - BasicDLL* pThis = BASIC_DLL; - DBG_ASSERT( pThis, "BasicDLL::EnableBreak: No instance yet!" ); - if ( pThis ) + DBG_ASSERT( BasicDLLImpl::BASIC_DLL, "BasicDLL::EnableBreak: No instance yet!" ); + if (BasicDLLImpl::BASIC_DLL) { - pThis->m_xImpl->bDebugMode = bDebugMode; + BasicDLLImpl::BASIC_DLL->bDebugMode = bDebugMode; } } void BasicDLL::BasicBreak() { - BasicDLL* pThis = BASIC_DLL; - DBG_ASSERT( pThis, "BasicDLL::EnableBreak: No instance yet!" ); + DBG_ASSERT( BasicDLLImpl::BASIC_DLL, "BasicDLL::EnableBreak: No instance yet!" ); #if HAVE_FEATURE_SCRIPTING - if ( pThis ) + if (BasicDLLImpl::BASIC_DLL) { // bJustStopping: if there's someone pressing STOP like crazy umpteen times, // but the Basic doesn't stop early enough, the box might appear more often... static bool bJustStopping = false; if (StarBASIC::IsRunning() && !bJustStopping - && (pThis->m_xImpl->bBreakEnabled || pThis->m_xImpl->bDebugMode)) + && (BasicDLLImpl::BASIC_DLL->bBreakEnabled || BasicDLLImpl::BASIC_DLL->bDebugMode)) { bJustStopping = true; StarBASIC::Stop(); @@ -106,7 +117,7 @@ void BasicDLL::BasicBreak() SbxAppData& GetSbxData_Impl() { - return *BASIC_DLL->m_xImpl->xSbxAppData; + return *BasicDLLImpl::BASIC_DLL->xSbxAppData; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |