summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2011-05-11 11:24:22 +0100
committerCaolán McNamara <caolanm@redhat.com>2011-05-20 15:23:07 +0100
commit04626c26b3f89d968029226c7e3268f0c1ef281a (patch)
tree2d4a2fea58baeeca9fad70327b369e80c010ee79 /drawinglayer
parent93b6f50f4456818a6771d32eddad0a9863175538 (diff)
config leak: gracefully handle exit before release timer is called
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/primitive2d/textlayoutdevice.cxx61
1 files changed, 36 insertions, 25 deletions
diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index 0ec1263488..0c37200c77 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()