LCOV - code coverage report
Current view: top level - libreoffice/cppuhelper/source - component.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 57 83 68.7 %
Date: 2012-12-27 Functions: 10 12 83.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             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <rtl/string.hxx>
      21             : #include <osl/diagnose.h>
      22             : #include <cppuhelper/component.hxx>
      23             : #include <cppuhelper/queryinterface.hxx>
      24             : #include <cppuhelper/typeprovider.hxx>
      25             : #include "com/sun/star/uno/RuntimeException.hpp"
      26             : 
      27             : using namespace osl;
      28             : using namespace com::sun::star;
      29             : using namespace com::sun::star::uno;
      30             : using namespace com::sun::star::lang;
      31             : 
      32             : using ::rtl::OUString;
      33             : using ::rtl::OString;
      34             : using ::rtl::OUStringToOString;
      35             : 
      36             : namespace cppu
      37             : {
      38             : 
      39             : //  ----------------------------------------------------
      40             : //  class OComponentHelper
      41             : //  ----------------------------------------------------
      42             : 
      43        6529 : OComponentHelper::OComponentHelper( Mutex & rMutex ) SAL_THROW(())
      44        6529 :     : rBHelper( rMutex )
      45             : {
      46        6529 : }
      47        5276 : OComponentHelper::~OComponentHelper() SAL_THROW( (RuntimeException) )
      48             : {
      49        5276 : }
      50             : 
      51       23051 : Any OComponentHelper::queryInterface( Type const & rType ) throw (RuntimeException)
      52             : {
      53       23051 :     return OWeakAggObject::queryInterface( rType );
      54             : }
      55       22594 : Any OComponentHelper::queryAggregation( Type const & rType ) throw (RuntimeException)
      56             : {
      57       22594 :     if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
      58             :     {
      59        5115 :         void * p = static_cast< lang::XComponent * >( this );
      60        5115 :         return Any( &p, rType );
      61             :     }
      62       17479 :     else if (rType == ::getCppuType( (Reference< lang::XTypeProvider > const *)0 ))
      63             :     {
      64           0 :         void * p = static_cast< lang::XTypeProvider * >( this );
      65           0 :         return Any( &p, rType );
      66             :     }
      67       17479 :     return OWeakAggObject::queryAggregation( rType );
      68             : }
      69      132866 : void OComponentHelper::acquire() throw ()
      70             : {
      71      132866 :     OWeakAggObject::acquire();
      72      132866 : }
      73             : 
      74      129802 : void OComponentHelper::release() throw()
      75             : {
      76      129802 :     Reference<XInterface > x( xDelegator );
      77      129802 :     if (! x.is())
      78             :     {
      79      129802 :         if (osl_atomic_decrement( &m_refCount ) == 0)
      80             :         {
      81        7332 :             if (! rBHelper.bDisposed)
      82             :             {
      83             :                 // *before* again incrementing our ref count, ensure that our weak connection point
      84             :                 // will not create references to us anymore (via XAdapter::queryAdapted)
      85        2284 :                 disposeWeakConnectionPoint();
      86             : 
      87        2284 :                 Reference<XInterface > xHoldAlive( *this );
      88             :                 // First dispose
      89             :                 try
      90             :                 {
      91        2284 :                     dispose();
      92             :                 }
      93           0 :                 catch (::com::sun::star::uno::RuntimeException & exc)
      94             :                 {
      95             :                     // release should not throw exceptions
      96             : #if OSL_DEBUG_LEVEL > 0
      97             :                     OString msg( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
      98             :                     OSL_FAIL( msg.getStr() );
      99             : #else
     100             :                     (void) exc; // avoid warning about unused variable
     101             : #endif
     102             :                 }
     103             : 
     104             :                 // only the alive ref holds the object
     105             :                 OSL_ASSERT( m_refCount == 1 );
     106             :                 // destroy the object if xHoldAlive decrement the refcount to 0
     107      132086 :                 return;
     108             :             }
     109             :         }
     110             :         // restore the reference count
     111      127518 :         osl_atomic_increment( &m_refCount );
     112             :     }
     113      127518 :     OWeakAggObject::release();
     114             : }
     115             : 
     116           0 : Sequence< Type > OComponentHelper::getTypes() throw (RuntimeException)
     117             : {
     118             :     static OTypeCollection * s_pTypes = 0;
     119           0 :     if (! s_pTypes)
     120             :     {
     121           0 :         MutexGuard aGuard( Mutex::getGlobalMutex() );
     122           0 :         if (! s_pTypes)
     123             :         {
     124             :             static OTypeCollection s_aTypes(
     125           0 :                 ::getCppuType( (const Reference< lang::XComponent > *)0 ),
     126           0 :                 ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ),
     127           0 :                 ::getCppuType( (const Reference< XAggregation > *)0 ),
     128           0 :                 ::getCppuType( (const Reference< XWeak > *)0 ) );
     129           0 :             s_pTypes = &s_aTypes;
     130           0 :         }
     131             :     }
     132           0 :     return s_pTypes->getTypes();
     133             : }
     134             : 
     135             : // XComponent
     136        5150 : void OComponentHelper::disposing()
     137             : {
     138        5150 : }
     139             : 
     140             : // XComponent
     141        5207 : void OComponentHelper::dispose()
     142             :     throw(::com::sun::star::uno::RuntimeException)
     143             : {
     144             :     // An frequently programming error is to release the last
     145             :     // reference to this object in the disposing message.
     146             :     // Make it rubust, hold a self Reference.
     147        5207 :     Reference<XComponent > xSelf( this );
     148             : 
     149             :     // Guard dispose against multible threading
     150             :     // Remark: It is an error to call dispose more than once
     151        5207 :     sal_Bool bDoDispose = sal_False;
     152             :     {
     153        5207 :     MutexGuard aGuard( rBHelper.rMutex );
     154        5207 :     if( !rBHelper.bDisposed && !rBHelper.bInDispose )
     155             :     {
     156             :         // only one call go into this section
     157        5207 :         rBHelper.bInDispose = sal_True;
     158        5207 :         bDoDispose = sal_True;
     159        5207 :     }
     160             :     }
     161             : 
     162             :     // Do not hold the mutex because we are broadcasting
     163        5207 :     if( bDoDispose )
     164             :     {
     165             :         // Create an event with this as sender
     166             :         try
     167             :         {
     168             :             try
     169             :             {
     170             :                 Reference<XInterface > xSource(
     171        5207 :                     Reference<XInterface >::query( (XComponent *)this ) );
     172        5207 :                 EventObject aEvt;
     173        5207 :                 aEvt.Source = xSource;
     174             :                 // inform all listeners to release this object
     175             :                 // The listener container are automaticly cleared
     176        5207 :                 rBHelper.aLC.disposeAndClear( aEvt );
     177             :                 // notify subclasses to do their dispose
     178        5207 :                 disposing();
     179             :             }
     180           0 :             catch (...)
     181             :             {
     182           0 :                 MutexGuard aGuard( rBHelper.rMutex );
     183             :                 // bDispose and bInDisposing must be set in this order:
     184           0 :                 rBHelper.bDisposed = sal_True;
     185           0 :                 rBHelper.bInDispose = sal_False;
     186           0 :                 throw;
     187             :             }
     188        5207 :             MutexGuard aGuard( rBHelper.rMutex );
     189             :             // bDispose and bInDisposing must be set in this order:
     190        5207 :             rBHelper.bDisposed = sal_True;
     191        5207 :             rBHelper.bInDispose = sal_False;
     192             :         }
     193           0 :         catch (RuntimeException &)
     194             :         {
     195           0 :             throw;
     196             :         }
     197           0 :         catch (Exception & exc)
     198             :         {
     199             :             throw RuntimeException(
     200             :                 OUString( RTL_CONSTASCII_USTRINGPARAM(
     201             :                               "unexpected UNO exception caught: ") ) +
     202           0 :                 exc.Message, Reference< XInterface >() );
     203             :         }
     204             :     }
     205             :     else
     206             :     {
     207             :         // in a multithreaded environment, it can't be avoided
     208             :         // that dispose is called twice.
     209             :         // However this condition is traced, because it MAY indicate an error.
     210             :         OSL_TRACE( "OComponentHelper::dispose() - dispose called twice" );
     211        5207 :     }
     212        5207 : }
     213             : 
     214             : // XComponent
     215        2192 : void OComponentHelper::addEventListener(
     216             :     const Reference<XEventListener > & rxListener )
     217             :     throw(::com::sun::star::uno::RuntimeException)
     218             : {
     219        2192 :     ClearableMutexGuard aGuard( rBHelper.rMutex );
     220        2192 :     if (rBHelper.bDisposed || rBHelper.bInDispose)
     221             :     {
     222           0 :         aGuard.clear();
     223           0 :         Reference< XInterface > x( (XComponent *)this, UNO_QUERY );
     224           0 :         rxListener->disposing( EventObject( x ) );
     225             :     }
     226             :     else
     227             :     {
     228        2192 :         rBHelper.addListener( ::getCppuType( &rxListener ) , rxListener );
     229        2192 :     }
     230        2192 : }
     231             : 
     232             : // XComponent
     233         102 : void OComponentHelper::removeEventListener(
     234             :     const Reference<XEventListener > & rxListener )
     235             :     throw(::com::sun::star::uno::RuntimeException)
     236             : {
     237         102 :     rBHelper.removeListener( ::getCppuType( &rxListener ) , rxListener );
     238         102 : }
     239             : 
     240             : }
     241             : 
     242             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10