diff options
author | Matthew J. Francis <mjay.francis@gmail.com> | 2014-09-24 23:30:23 +0800 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-09-25 10:45:31 +0200 |
commit | 0af1c09b3ad23790d9992ec329a2c3f28b820050 (patch) | |
tree | 6d8cfe8c4d3fb726ab5020c2d828340dec41306a /cppuhelper | |
parent | f5ba3098b4406ff8656f2710df8af6ca6edcddc8 (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>
Diffstat (limited to 'cppuhelper')
-rw-r--r-- | cppuhelper/source/servicemanager.cxx | 31 |
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; } |