summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basic/inc/sbxbase.hxx1
-rw-r--r--basic/source/basmgr/basicmanagerrepository.cxx20
-rw-r--r--basic/source/runtime/basrdll.cxx53
-rw-r--r--basic/source/sbx/sbxbase.cxx3
-rw-r--r--dbaccess/source/core/inc/databasecontext.hxx10
-rw-r--r--include/basic/basrdll.hxx7
-rw-r--r--include/unotest/macros_test.hxx11
-rw-r--r--sfx2/source/appl/app.cxx7
-rw-r--r--sfx2/source/appl/appdata.cxx7
-rw-r--r--unotest/source/cpp/macros_test.cxx8
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());