diff options
author | Caolán McNamara <caolanm@redhat.com> | 2011-05-11 11:24:22 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2011-05-20 15:23:07 +0100 |
commit | 990577d041aa3372062523c77af07dd6ac826b61 (patch) | |
tree | a498dec73751762767e2444e3dea9c8d20f3ea7b /drawinglayer | |
parent | 450479820265292adc825be84447cdb1379182c7 (diff) |
config leak: gracefully handle exit before release timer is called
Diffstat (limited to 'drawinglayer')
-rw-r--r-- | drawinglayer/source/primitive2d/textlayoutdevice.cxx | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx index 994d6569a095..330d597ba700 100644 --- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx +++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx @@ -30,6 +30,8 @@ #include "precompiled_drawinglayer.hxx" #include <drawinglayer/primitive2d/textlayoutdevice.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/scoped_disposing_ptr.hxx> #include <vcl/timer.hxx> #include <vcl/virdev.hxx> #include <vcl/font.hxx> @@ -43,14 +45,33 @@ namespace { + class ImpTimedRefDev; + + //the scoped_timed_RefDev owns a ImpTimeRefDev and releases it on dtor + //or disposing of the default XComponentContext which causes the underlying + //OutputDevice to get released + // + //The ImpTimerRefDev itself, if the timeout ever gets hit, will call + //reset on the scoped_timed_RefDev to release the ImpTimerRefDev early + //if its unused for a few minutes + class scoped_timed_RefDev : public comphelper::scoped_disposing_ptr<ImpTimedRefDev> + { + public: + scoped_timed_RefDev() : comphelper::scoped_disposing_ptr<ImpTimedRefDev>((::com::sun::star::uno::Reference<com::sun::star::lang::XComponent>(::comphelper::getProcessComponentContext(), ::com::sun::star::uno::UNO_QUERY_THROW))) + { + } + }; + + class the_scoped_timed_RefDev : public rtl::Static<scoped_timed_RefDev, the_scoped_timed_RefDev> {}; + class ImpTimedRefDev : public Timer { - ImpTimedRefDev** mppStaticPointerOnMe; + scoped_timed_RefDev& mrOwnerOfMe; VirtualDevice* mpVirDev; sal_uInt32 mnUseCount; public: - ImpTimedRefDev(ImpTimedRefDev** ppStaticPointerOnMe); + ImpTimedRefDev(scoped_timed_RefDev& rOwnerofMe); ~ImpTimedRefDev(); virtual void Timeout(); @@ -58,8 +79,8 @@ namespace void releaseVirtualDevice(); }; - ImpTimedRefDev::ImpTimedRefDev(ImpTimedRefDev** ppStaticPointerOnMe) - : mppStaticPointerOnMe(ppStaticPointerOnMe), + ImpTimedRefDev::ImpTimedRefDev(scoped_timed_RefDev& rOwnerOfMe) + : mrOwnerOfMe(rOwnerOfMe), mpVirDev(0L), mnUseCount(0L) { @@ -70,22 +91,13 @@ namespace ImpTimedRefDev::~ImpTimedRefDev() { OSL_ENSURE(0L == mnUseCount, "destruction of a still used ImpTimedRefDev (!)"); - - if(mppStaticPointerOnMe && *mppStaticPointerOnMe) - { - *mppStaticPointerOnMe = 0L; - } - - if(mpVirDev) - { - delete mpVirDev; - } + delete mpVirDev; } void ImpTimedRefDev::Timeout() { // for obvious reasons, do not call anything after this - delete (this); + mrOwnerOfMe.reset(); } VirtualDevice& ImpTimedRefDev::acquireVirtualDevice() @@ -125,24 +137,23 @@ namespace drawinglayer { namespace primitive2d { - // static pointer here - static ImpTimedRefDev* pImpGlobalRefDev = 0L; - // static methods here VirtualDevice& acquireGlobalVirtualDevice() { - if(!pImpGlobalRefDev) - { - pImpGlobalRefDev = new ImpTimedRefDev(&pImpGlobalRefDev); - } + scoped_timed_RefDev& rStdRefDevice = the_scoped_timed_RefDev::get(); - return pImpGlobalRefDev->acquireVirtualDevice(); + if(!rStdRefDevice) + rStdRefDevice.reset(new ImpTimedRefDev(rStdRefDevice)); + + return rStdRefDevice->acquireVirtualDevice(); } void releaseGlobalVirtualDevice() { - OSL_ENSURE(pImpGlobalRefDev, "releaseGlobalVirtualDevice() without prior acquireGlobalVirtualDevice() call(!)"); - pImpGlobalRefDev->releaseVirtualDevice(); + scoped_timed_RefDev& rStdRefDevice = the_scoped_timed_RefDev::get(); + + OSL_ENSURE(rStdRefDevice, "releaseGlobalVirtualDevice() without prior acquireGlobalVirtualDevice() call(!)"); + rStdRefDevice->releaseVirtualDevice(); } TextLayouterDevice::TextLayouterDevice() |