summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew J. Francis <mjay.francis@gmail.com>2014-09-24 23:30:23 +0800
committerStephan Bergmann <sbergman@redhat.com>2014-09-25 10:45:31 +0200
commit0af1c09b3ad23790d9992ec329a2c3f28b820050 (patch)
tree6d8cfe8c4d3fb726ab5020c2d828340dec41306a
parentf5ba3098b4406ff8656f2710df8af6ca6edcddc8 (diff)
Eliminate memory leak due to circular shared_ptr
Without this, a Data::Implementation can have a circular reference of shared_ptr to itself through .factory1 Change-Id: Ie05545e7ecc0ae85256d2c374fe79f0c678ccf64 Signed-off-by: Stephan Bergmann <sbergman@redhat.com>
-rw-r--r--cppuhelper/source/servicemanager.cxx31
1 files changed, 20 insertions, 11 deletions
diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx
index 84b29b331375..ed8e9ecbbfca 100644
--- a/cppuhelper/source/servicemanager.cxx
+++ b/cppuhelper/source/servicemanager.cxx
@@ -15,6 +15,7 @@
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/container/ElementExistException.hpp>
@@ -586,7 +587,7 @@ private:
getSupportedServiceNames() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
rtl::Reference< cppuhelper::ServiceManager > manager_;
- boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation >
+ boost::weak_ptr< cppuhelper::ServiceManager::Data::Implementation >
implementation_;
};
@@ -595,8 +596,10 @@ ImplementationWrapper::createInstanceWithContext(
css::uno::Reference< css::uno::XComponentContext > const & Context)
throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
{
- manager_->loadImplementation(Context, implementation_);
- return implementation_->createInstance(Context, false);
+ boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > impl = implementation_.lock();
+ assert(impl);
+ manager_->loadImplementation(Context, impl);
+ return impl->createInstance(Context, false);
}
css::uno::Reference< css::uno::XInterface >
@@ -605,8 +608,10 @@ ImplementationWrapper::createInstanceWithArgumentsAndContext(
css::uno::Reference< css::uno::XComponentContext > const & Context)
throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
{
- manager_->loadImplementation(Context, implementation_);
- return implementation_->createInstanceWithArguments(
+ boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > impl = implementation_.lock();
+ assert(impl);
+ manager_->loadImplementation(Context, impl);
+ return impl->createInstanceWithArguments(
Context, false, Arguments);
}
@@ -629,7 +634,9 @@ ImplementationWrapper::createInstanceWithArguments(
rtl::OUString ImplementationWrapper::getImplementationName()
throw (css::uno::RuntimeException, std::exception)
{
- return implementation_->info->name;
+ boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > impl = implementation_.lock();
+ assert(impl);
+ return impl->info->name;
}
sal_Bool ImplementationWrapper::supportsService(rtl::OUString const & ServiceName)
@@ -642,20 +649,22 @@ css::uno::Sequence< rtl::OUString >
ImplementationWrapper::getSupportedServiceNames()
throw (css::uno::RuntimeException, std::exception)
{
- if (implementation_->info->services.size()
+ boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > impl = implementation_.lock();
+ assert(impl);
+ if (impl->info->services.size()
> static_cast< sal_uInt32 >(SAL_MAX_INT32))
{
throw css::uno::RuntimeException(
- ("Implementation " + implementation_->info->name
+ ("Implementation " + impl->info->name
+ " supports too many services"),
static_cast< cppu::OWeakObject * >(this));
}
css::uno::Sequence< rtl::OUString > names(
- static_cast< sal_Int32 >(implementation_->info->services.size()));
+ static_cast< sal_Int32 >(impl->info->services.size()));
sal_Int32 i = 0;
for (std::vector< rtl::OUString >::const_iterator j(
- implementation_->info->services.begin());
- j != implementation_->info->services.end(); ++j)
+ impl->info->services.begin());
+ j != impl->info->services.end(); ++j)
{
names[i++] = *j;
}