diff options
-rw-r--r-- | basic/inc/sbxbase.hxx | 1 | ||||
-rw-r--r-- | basic/source/basmgr/basicmanagerrepository.cxx | 20 | ||||
-rw-r--r-- | basic/source/runtime/basrdll.cxx | 53 | ||||
-rw-r--r-- | basic/source/sbx/sbxbase.cxx | 3 | ||||
-rw-r--r-- | dbaccess/source/core/inc/databasecontext.hxx | 10 | ||||
-rw-r--r-- | include/basic/basrdll.hxx | 7 | ||||
-rw-r--r-- | include/unotest/macros_test.hxx | 11 | ||||
-rw-r--r-- | sfx2/source/appl/app.cxx | 7 | ||||
-rw-r--r-- | sfx2/source/appl/appdata.cxx | 7 | ||||
-rw-r--r-- | unotest/source/cpp/macros_test.cxx | 8 |
10 files changed, 92 insertions, 35 deletions
diff --git a/basic/inc/sbxbase.hxx b/basic/inc/sbxbase.hxx index a4ea06678f27..269f6029a55a 100644 --- a/basic/inc/sbxbase.hxx +++ b/basic/inc/sbxbase.hxx @@ -40,6 +40,7 @@ struct SbxAppData SbxVariableRef m_aGlobErr; // Global error object std::vector<std::unique_ptr<SbxFactory>> m_Factories; + tools::SvRef<SvRefBase> mrImplRepository; // Pointer to Format()-Command helper class std::unique_ptr<SbxBasicFormater> pBasicFormater; diff --git a/basic/source/basmgr/basicmanagerrepository.cxx b/basic/source/basmgr/basicmanagerrepository.cxx index 9116dbd382f1..01ca8759e145 100644 --- a/basic/source/basmgr/basicmanagerrepository.cxx +++ b/basic/source/basmgr/basicmanagerrepository.cxx @@ -22,6 +22,7 @@ #include <scriptcont.hxx> #include <dlgcont.hxx> #include <sbintern.hxx> +#include <sbxbase.hxx> #include <com/sun/star/document/XStorageBasedDocument.hpp> #include <com/sun/star/document/XEmbeddedScripts.hpp> @@ -62,10 +63,11 @@ namespace basic typedef std::vector< BasicManagerCreationListener* > CreationListeners; - class ImplRepository : public ::utl::OEventListenerAdapter, public SfxListener + class ImplRepository : public ::utl::OEventListenerAdapter, public SfxListener, public SvRefBase { private: ImplRepository(); + ~ImplRepository(); private: BasicManagerStore m_aStore; @@ -193,11 +195,23 @@ namespace basic { } + ImplRepository::~ImplRepository() + { + // Avoid double-delete of managers when they are destroyed in our dtor, and start notify us + for (auto& it : m_aStore) + EndListening(*it.second); + } ImplRepository& ImplRepository::Instance() { - static ImplRepository repository; - return repository; + tools::SvRef<SvRefBase>& repository = GetSbxData_Impl().mrImplRepository; + { + static osl::Mutex aMutex; + osl::MutexGuard aGuard(aMutex); + if (!repository) + repository = new ImplRepository; + } + return *static_cast<ImplRepository*>(repository.get()); } BasicManager* ImplRepository::getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel ) 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: */ diff --git a/basic/source/sbx/sbxbase.cxx b/basic/source/sbx/sbxbase.cxx index d1b17d4fa288..431a5ae5e612 100644 --- a/basic/source/sbx/sbxbase.cxx +++ b/basic/source/sbx/sbxbase.cxx @@ -46,6 +46,9 @@ SbxAppData::~SbxAppData() SolarMutexGuard g; pBasicFormater.reset(); + m_aGlobErr.clear(); + // basic manager repository must be destroyed before factories + mrImplRepository.clear(); m_Factories.clear(); } diff --git a/dbaccess/source/core/inc/databasecontext.hxx b/dbaccess/source/core/inc/databasecontext.hxx index 19c59a953f9d..6f5c2cb19d55 100644 --- a/dbaccess/source/core/inc/databasecontext.hxx +++ b/dbaccess/source/core/inc/databasecontext.hxx @@ -22,6 +22,8 @@ #include <sal/config.h> +#include <config_features.h> + #include <map> #include "ModelImpl.hxx" @@ -41,6 +43,10 @@ #include <com/sun/star/uno/XNamingService.hpp> #include <com/sun/star/uno/XAggregation.hpp> +#if HAVE_FEATURE_SCRIPTING +#include <basic/basrdll.hxx> +#endif + #include <basic/basicmanagerrepository.hxx> #include <cppuhelper/compbase.hxx> #include <cppuhelper/interfacecontainer.hxx> @@ -85,6 +91,10 @@ private: css::uno::Reference< css::uno::XInterface > impl_createNewDataSource(); +#if HAVE_FEATURE_SCRIPTING + BasicDLL m_aBasicDLL; +#endif + protected: ::osl::Mutex m_aMutex; css::uno::Reference< css::uno::XComponentContext > diff --git a/include/basic/basrdll.hxx b/include/basic/basrdll.hxx index e4e97ae65dbc..53768deb5760 100644 --- a/include/basic/basrdll.hxx +++ b/include/basic/basrdll.hxx @@ -21,13 +21,12 @@ #define INCLUDED_BASIC_BASRDLL_HXX #include <basic/basicdllapi.h> -#include <memory> +#include <tools/ref.hxx> class BASIC_DLLPUBLIC BasicDLL { -public: - struct Impl; - std::unique_ptr<Impl> m_xImpl; +private: + tools::SvRef<SvRefBase> m_xImpl; public: BasicDLL(); diff --git a/include/unotest/macros_test.hxx b/include/unotest/macros_test.hxx index 6ec5c25167df..4dcf9427fbf9 100644 --- a/include/unotest/macros_test.hxx +++ b/include/unotest/macros_test.hxx @@ -10,6 +10,9 @@ #ifndef INCLUDED_UNOTEST_MACROS_TEST_HXX #define INCLUDED_UNOTEST_MACROS_TEST_HXX +#include <sal/config.h> + +#include <memory> #include <rtl/ustring.hxx> #include <unotest/detail/unotestdllapi.hxx> @@ -22,16 +25,24 @@ struct TestMacroInfo OUString sMacroUrl; }; +class BasicDLL; + namespace unotest { class OOO_DLLPUBLIC_UNOTEST MacrosTest { public: + MacrosTest(); + ~MacrosTest(); + css::uno::Reference< css::lang::XComponent > loadFromDesktop(const OUString& rURL, const OUString& rDocService = OUString(), const css::uno::Sequence<css::beans::PropertyValue>& rExtra_args = css::uno::Sequence<css::beans::PropertyValue>() ); protected: css::uno::Reference< css::frame::XDesktop2> mxDesktop; + +private: + std::unique_ptr<BasicDLL> mpDll; }; } diff --git a/sfx2/source/appl/app.cxx b/sfx2/source/appl/app.cxx index fafddce19064..c09b415825f6 100644 --- a/sfx2/source/appl/app.cxx +++ b/sfx2/source/appl/app.cxx @@ -24,7 +24,6 @@ #include <sfx2/app.hxx> #include <sfx2/frame.hxx> -#include <basic/basrdll.hxx> #include <basic/sberrors.hxx> #include <tools/svlibrary.h> @@ -65,8 +64,6 @@ using namespace ::com::sun::star; static SfxApplication* g_pSfxApplication = nullptr; -static BasicDLL* pBasic = nullptr; - #if HAVE_FEATURE_DESKTOP static SfxHelp* pSfxHelp = nullptr; #endif @@ -160,8 +157,6 @@ SfxApplication::SfxApplication() pSfxHelp = new SfxHelp; #endif - pBasic = new BasicDLL; - #if HAVE_FEATURE_SCRIPTING StarBASIC::SetGlobalErrorHdl( LINK( this, SfxApplication, GlobalBasicErrorHdl_Impl ) ); #endif @@ -190,8 +185,6 @@ SfxApplication::~SfxApplication() if ( !pImpl->bDowning ) Deinitialize(); - delete pBasic; - g_pSfxApplication = nullptr; } diff --git a/sfx2/source/appl/appdata.cxx b/sfx2/source/appl/appdata.cxx index e37fc0e1e73e..1b74848f39cf 100644 --- a/sfx2/source/appl/appdata.cxx +++ b/sfx2/source/appl/appdata.cxx @@ -31,6 +31,7 @@ #include <basic/basicmanagerrepository.hxx> #include <basic/basmgr.hxx> +#include <basic/basrdll.hxx> using ::basic::BasicManagerRepository; using ::basic::BasicManagerCreationListener; @@ -38,6 +39,8 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::frame::XModel; using ::com::sun::star::uno::XInterface; +static BasicDLL* pBasic = nullptr; + class SfxBasicManagerCreationListener : public ::basic::BasicManagerCreationListener { private: @@ -91,6 +94,8 @@ SfxAppData_Impl::SfxAppData_Impl() , bInQuit( false ) { + pBasic = new BasicDLL; + #if HAVE_FEATURE_SCRIPTING BasicManagerRepository::registerCreationListener( *pBasMgrListener ); #endif @@ -105,6 +110,8 @@ SfxAppData_Impl::~SfxAppData_Impl() BasicManagerRepository::revokeCreationListener( *pBasMgrListener ); pBasMgrListener.reset(); #endif + + delete pBasic; } SfxDocumentTemplates* SfxAppData_Impl::GetDocumentTemplates() diff --git a/unotest/source/cpp/macros_test.cxx b/unotest/source/cpp/macros_test.cxx index ffc2b970393c..758dcc707347 100644 --- a/unotest/source/cpp/macros_test.cxx +++ b/unotest/source/cpp/macros_test.cxx @@ -14,6 +14,7 @@ #include <com/sun/star/frame/XComponentLoader.hpp> #include <com/sun/star/document/MacroExecMode.hpp> +#include <basic/basrdll.hxx> #include <cppunit/TestAssert.h> #include <rtl/ustrbuf.hxx> #include <comphelper/sequence.hxx> @@ -22,6 +23,13 @@ using namespace css; namespace unotest { +MacrosTest::MacrosTest() + : mpDll(std::make_unique<BasicDLL>()) +{ +} + +MacrosTest::~MacrosTest() = default; + uno::Reference<css::lang::XComponent> MacrosTest::loadFromDesktop(const OUString& rURL, const OUString& rDocService, const uno::Sequence<beans::PropertyValue>& rExtraArgs) { CPPUNIT_ASSERT_MESSAGE("no desktop", mxDesktop.is()); |