LCOV - code coverage report
Current view: top level - libreoffice/solver/unxlngi6.pro/inc/comphelper - scoped_disposing_ptr.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 52 55 94.5 %
Date: 2012-12-17 Functions: 35 59 59.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
       4             :  *
       5             :  * The contents of this file are subject to the Mozilla Public License Version
       6             :  * 1.1 (the "License"); you may not use this file except in compliance with
       7             :  * the License or as specified alternatively below. You may obtain a copy of
       8             :  * the License at http://www.mozilla.org/MPL/
       9             :  *
      10             :  * Software distributed under the License is distributed on an "AS IS" basis,
      11             :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12             :  * for the specific language governing rights and limitations under the
      13             :  * License.
      14             :  *
      15             :  * Major Contributor(s):
      16             :  * Copyright (C) 2011 Red Hat, Inc., Caolán McNamara <caolanm@redhat.com>
      17             :  *  (initial developer)
      18             :  *
      19             :  * All Rights Reserved.
      20             :  *
      21             :  * For minor contributions see the git repository.
      22             :  *
      23             :  * Alternatively, the contents of this file may be used under the terms of
      24             :  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      25             :  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
      26             :  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
      27             :  * instead of those above.
      28             :  */
      29             : 
      30             : #ifndef _SCOPED_DISPOSING_PTR
      31             : #define _SCOPED_DISPOSING_PTR
      32             : 
      33             : #include <cppuhelper/implbase1.hxx>
      34             : #include <boost/utility.hpp>
      35             : #include <boost/scoped_ptr.hpp>
      36             : 
      37             : #include <com/sun/star/lang/XComponent.hpp>
      38             : #include <com/sun/star/frame/XDesktop.hpp>
      39             : 
      40             : // for locking SolarMutex: svapp + mutex
      41             : #include <vcl/svapp.hxx>
      42             : #include <osl/mutex.hxx>
      43             : 
      44             : namespace comphelper
      45             : {
      46             : //Similar to boost::scoped_ptr, except additionally releases the ptr on XComponent::disposing and/or XTerminateListener::notifyTermination if supported
      47             : template<class T> class scoped_disposing_ptr : private boost::noncopyable
      48             : {
      49             : private:
      50             :     boost::scoped_ptr<T> m_aItem;
      51             :     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTerminateListener> m_xTerminateListener;
      52             : public:
      53         102 :     scoped_disposing_ptr( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > &rComponent, T * p = 0 )
      54         102 :         : m_aItem(p)
      55             :     {
      56         102 :         m_xTerminateListener = new TerminateListener(rComponent, *this);
      57         102 :     }
      58             : 
      59         282 :     virtual void reset(T * p = 0)
      60             :     {
      61         282 :         m_aItem.reset(p);
      62         282 :     }
      63             : 
      64             :     T & operator*() const
      65             :     {
      66             :         return *m_aItem;
      67             :     }
      68             : 
      69       16252 :     T * get() const
      70             :     {
      71       16252 :         return m_aItem.get();
      72             :     }
      73             : 
      74         932 :     T * operator->() const
      75             :     {
      76         932 :         return m_aItem.get();
      77             :     }
      78             : 
      79       16670 :     operator bool () const
      80             :     {
      81       16670 :         return m_aItem;
      82             :     }
      83             : 
      84         102 :     virtual ~scoped_disposing_ptr()
      85             :     {
      86         204 :         reset();
      87         306 :     }
      88             : private:
      89             :     class TerminateListener : public ::cppu::WeakImplHelper1< ::com::sun::star::frame::XTerminateListener >
      90             :     {
      91             :     private:
      92             :         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > m_xComponent;
      93             :         scoped_disposing_ptr<T>& m_rItem;
      94             :     public:
      95         102 :         TerminateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > &rComponent,
      96         102 :             scoped_disposing_ptr<T>& rItem) : m_xComponent(rComponent), m_rItem(rItem)
      97             :         {
      98         102 :             if (m_xComponent.is())
      99             :             {
     100         102 :                 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop> xDesktop(m_xComponent, ::com::sun::star::uno::UNO_QUERY);
     101         102 :                 if (xDesktop.is())
     102          24 :                     xDesktop->addTerminateListener(this);
     103             :                 else
     104          78 :                     m_xComponent->addEventListener(this);
     105             :             }
     106         102 :         }
     107             : 
     108         204 :         ~TerminateListener()
     109             :         {
     110         102 :             if ( m_xComponent.is() )
     111             :             {
     112           0 :                 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop> xDesktop(m_xComponent, ::com::sun::star::uno::UNO_QUERY);
     113           0 :                 if (xDesktop.is())
     114           0 :                     xDesktop->removeTerminateListener(this);
     115             :                 else
     116         102 :                     m_xComponent->removeEventListener(this);
     117             :             }
     118         408 :         }
     119             : 
     120             :     private:
     121             :         // XEventListener
     122         102 :         virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& rEvt )
     123             :             throw (::com::sun::star::uno::RuntimeException)
     124             :         {
     125         102 :             bool shutDown = (rEvt.Source == m_xComponent);
     126             : 
     127         102 :             if (shutDown && m_xComponent.is())
     128             :             {
     129         102 :                 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop> xDesktop(m_xComponent, ::com::sun::star::uno::UNO_QUERY);
     130         102 :                 if (xDesktop.is())
     131          24 :                     xDesktop->removeTerminateListener(this);
     132             :                 else
     133          78 :                     m_xComponent->removeEventListener(this);
     134         102 :                 m_xComponent.clear();
     135             :             }
     136             : 
     137         102 :             if (shutDown)
     138         102 :                m_rItem.reset();
     139         102 :         }
     140             : 
     141             :         // XTerminateListener
     142           2 :         virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& )
     143             :             throw(::com::sun::star::frame::TerminationVetoException,
     144             :                   ::com::sun::star::uno::RuntimeException)
     145             :         {
     146           2 :         }
     147             : 
     148           2 :         virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& rEvt )
     149             :             throw (::com::sun::star::uno::RuntimeException)
     150             :         {
     151           2 :             disposing(rEvt);
     152           2 :         }
     153             :    };
     154             : };
     155             : 
     156             : //Something like an OutputDevice requires the SolarMutex to be taken before use
     157             : //for threadsafety. The user can ensure this, except in the case of its dtor
     158             : //being called from reset due to a terminate on the XComponent being called
     159             : //from an aribitrary thread
     160          88 : template<class T> class scoped_disposing_solar_mutex_reset_ptr
     161             :     : public scoped_disposing_ptr<T>
     162             : {
     163             : public:
     164          88 :     scoped_disposing_solar_mutex_reset_ptr( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > &rComponent, T * p = 0 )
     165          88 :         : scoped_disposing_ptr<T>(rComponent, p)
     166             :     {
     167          88 :     }
     168             : 
     169         152 :     virtual void reset(T * p = 0)
     170             :     {
     171         152 :         SolarMutexGuard aGuard;
     172         152 :         scoped_disposing_ptr<T>::reset(p);
     173         152 :     }
     174             : };
     175             : 
     176             : }
     177             : 
     178             : #endif
     179             : 
     180             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10