Kaydet (Commit) 990577d0 authored tarafından Caolán McNamara's avatar Caolán McNamara

config leak: gracefully handle exit before release timer is called

üst 45047982
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "precompiled_drawinglayer.hxx" #include "precompiled_drawinglayer.hxx"
#include <drawinglayer/primitive2d/textlayoutdevice.hxx> #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/scoped_disposing_ptr.hxx>
#include <vcl/timer.hxx> #include <vcl/timer.hxx>
#include <vcl/virdev.hxx> #include <vcl/virdev.hxx>
#include <vcl/font.hxx> #include <vcl/font.hxx>
...@@ -43,14 +45,33 @@ ...@@ -43,14 +45,33 @@
namespace 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 class ImpTimedRefDev : public Timer
{ {
ImpTimedRefDev** mppStaticPointerOnMe; scoped_timed_RefDev& mrOwnerOfMe;
VirtualDevice* mpVirDev; VirtualDevice* mpVirDev;
sal_uInt32 mnUseCount; sal_uInt32 mnUseCount;
public: public:
ImpTimedRefDev(ImpTimedRefDev** ppStaticPointerOnMe); ImpTimedRefDev(scoped_timed_RefDev& rOwnerofMe);
~ImpTimedRefDev(); ~ImpTimedRefDev();
virtual void Timeout(); virtual void Timeout();
...@@ -58,8 +79,8 @@ namespace ...@@ -58,8 +79,8 @@ namespace
void releaseVirtualDevice(); void releaseVirtualDevice();
}; };
ImpTimedRefDev::ImpTimedRefDev(ImpTimedRefDev** ppStaticPointerOnMe) ImpTimedRefDev::ImpTimedRefDev(scoped_timed_RefDev& rOwnerOfMe)
: mppStaticPointerOnMe(ppStaticPointerOnMe), : mrOwnerOfMe(rOwnerOfMe),
mpVirDev(0L), mpVirDev(0L),
mnUseCount(0L) mnUseCount(0L)
{ {
...@@ -70,22 +91,13 @@ namespace ...@@ -70,22 +91,13 @@ namespace
ImpTimedRefDev::~ImpTimedRefDev() ImpTimedRefDev::~ImpTimedRefDev()
{ {
OSL_ENSURE(0L == mnUseCount, "destruction of a still used ImpTimedRefDev (!)"); OSL_ENSURE(0L == mnUseCount, "destruction of a still used ImpTimedRefDev (!)");
delete mpVirDev;
if(mppStaticPointerOnMe && *mppStaticPointerOnMe)
{
*mppStaticPointerOnMe = 0L;
}
if(mpVirDev)
{
delete mpVirDev;
}
} }
void ImpTimedRefDev::Timeout() void ImpTimedRefDev::Timeout()
{ {
// for obvious reasons, do not call anything after this // for obvious reasons, do not call anything after this
delete (this); mrOwnerOfMe.reset();
} }
VirtualDevice& ImpTimedRefDev::acquireVirtualDevice() VirtualDevice& ImpTimedRefDev::acquireVirtualDevice()
...@@ -125,24 +137,23 @@ namespace drawinglayer ...@@ -125,24 +137,23 @@ namespace drawinglayer
{ {
namespace primitive2d namespace primitive2d
{ {
// static pointer here
static ImpTimedRefDev* pImpGlobalRefDev = 0L;
// static methods here // static methods here
VirtualDevice& acquireGlobalVirtualDevice() VirtualDevice& acquireGlobalVirtualDevice()
{ {
if(!pImpGlobalRefDev) scoped_timed_RefDev& rStdRefDevice = the_scoped_timed_RefDev::get();
{
pImpGlobalRefDev = new ImpTimedRefDev(&pImpGlobalRefDev);
}
return pImpGlobalRefDev->acquireVirtualDevice(); if(!rStdRefDevice)
rStdRefDevice.reset(new ImpTimedRefDev(rStdRefDevice));
return rStdRefDevice->acquireVirtualDevice();
} }
void releaseGlobalVirtualDevice() void releaseGlobalVirtualDevice()
{ {
OSL_ENSURE(pImpGlobalRefDev, "releaseGlobalVirtualDevice() without prior acquireGlobalVirtualDevice() call(!)"); scoped_timed_RefDev& rStdRefDevice = the_scoped_timed_RefDev::get();
pImpGlobalRefDev->releaseVirtualDevice();
OSL_ENSURE(rStdRefDevice, "releaseGlobalVirtualDevice() without prior acquireGlobalVirtualDevice() call(!)");
rStdRefDevice->releaseVirtualDevice();
} }
TextLayouterDevice::TextLayouterDevice() TextLayouterDevice::TextLayouterDevice()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment