LCOV - code coverage report
Current view: top level - libreoffice/bridges/source/cpp_uno/shared - cppinterfaceproxy.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 55 60 91.7 %
Date: 2012-12-17 Functions: 11 12 91.7 %
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 "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
      21             : 
      22             : #include "guardedarray.hxx"
      23             : 
      24             : #include "bridges/cpp_uno/shared/bridge.hxx"
      25             : #include "bridges/cpp_uno/shared/vtablefactory.hxx"
      26             : 
      27             : #include "com/sun/star/uno/XInterface.hpp"
      28             : #include "osl/diagnose.h"
      29             : #include "osl/getglobalmutex.hxx"
      30             : #include "osl/interlck.h"
      31             : #include "osl/mutex.hxx"
      32             : #include "rtl/instance.hxx"
      33             : #include "typelib/typedescription.h"
      34             : 
      35             : #include <cstddef>
      36             : #include <new>
      37             : 
      38             : 
      39             : static bridges::cpp_uno::shared::VtableFactory * pInstance;
      40             : 
      41             : #if defined(__GNUG__) && !defined(__MINGW32__)
      42             : void dso_init(void) __attribute__((constructor));
      43             : void dso_exit(void) __attribute__((destructor));
      44             : #endif
      45             : 
      46         114 : void dso_init(void) {
      47         114 :     if (!pInstance)
      48         114 :         pInstance = new bridges::cpp_uno::shared::VtableFactory();
      49         114 : }
      50             : 
      51           0 : void dso_exit(void) {
      52           0 :     if (pInstance)
      53             :     {
      54           0 :         delete pInstance;
      55           0 :         pInstance = NULL;
      56             :     }
      57           0 : }
      58             : 
      59             : #ifdef __SUNPRO_CC
      60             : # pragma init(dso_init)
      61             : # pragma fini(dso_exit)
      62             : #endif
      63             : 
      64             : 
      65             : 
      66             : namespace {
      67             : 
      68             : struct InitVtableFactory {
      69          72 :     bridges::cpp_uno::shared::VtableFactory * operator()() {
      70          72 :         return pInstance;
      71             :     }
      72             : };
      73             : 
      74        6343 : bridges::cpp_uno::shared::VtableFactory * getVtableFactory() {
      75             :     return rtl_Instance<
      76             :         bridges::cpp_uno::shared::VtableFactory, InitVtableFactory,
      77             :         osl::MutexGuard, osl::GetGlobalMutex >::create(
      78        6343 :             InitVtableFactory(), osl::GetGlobalMutex());
      79             : }
      80             : 
      81             : }
      82             : 
      83             : namespace bridges { namespace cpp_uno { namespace shared {
      84             : 
      85        6343 : void freeCppInterfaceProxy(uno_ExtEnvironment * pEnv, void * pInterface)
      86             : {
      87             :     CppInterfaceProxy * pThis = CppInterfaceProxy::castInterfaceToProxy(
      88        6343 :         pInterface);
      89        6343 :     if (pEnv != pThis->pBridge->getCppEnv()) {
      90             :         OSL_ASSERT(false);
      91             :     }
      92             : 
      93        6343 :     (*pThis->pBridge->getUnoEnv()->revokeInterface)(
      94        6343 :         pThis->pBridge->getUnoEnv(), pThis->pUnoI );
      95        6343 :     (*pThis->pUnoI->release)( pThis->pUnoI );
      96             :     ::typelib_typedescription_release(
      97        6343 :         (typelib_TypeDescription *)pThis->pTypeDescr );
      98        6343 :     pThis->pBridge->release();
      99             : 
     100             : #if OSL_DEBUG_LEVEL > 1
     101             :     *(int *)pInterface = 0xdeadbabe;
     102             : #endif
     103        6343 :     pThis->~CppInterfaceProxy();
     104        6343 :     delete[] reinterpret_cast< char * >(pThis);
     105        6343 : }
     106             : 
     107        6343 : com::sun::star::uno::XInterface * CppInterfaceProxy::create(
     108             :     bridges::cpp_uno::shared::Bridge * pBridge, uno_Interface * pUnoI,
     109             :     typelib_InterfaceTypeDescription * pTypeDescr, OUString const & rOId)
     110             :     SAL_THROW(())
     111             : {
     112             :     typelib_typedescription_complete(
     113        6343 :         reinterpret_cast< typelib_TypeDescription ** >(&pTypeDescr));
     114             :     bridges::cpp_uno::shared::VtableFactory::Vtables aVtables(
     115        6343 :         getVtableFactory()->getVtables(pTypeDescr));
     116             :     bridges::cpp_uno::shared::GuardedArray< char > pMemory(
     117             :         new char[
     118             :             sizeof (CppInterfaceProxy)
     119        6343 :             + (aVtables.count - 1) * sizeof (void **)]);
     120        6343 :     new(pMemory.get()) CppInterfaceProxy(pBridge, pUnoI, pTypeDescr, rOId);
     121             :     CppInterfaceProxy * pProxy = reinterpret_cast< CppInterfaceProxy * >(
     122        6343 :         pMemory.release());
     123       12990 :     for (sal_Int32 i = 0; i < aVtables.count; ++i) {
     124             :         pProxy->vtables[i] = VtableFactory::mapBlockToVtable(
     125        6647 :             aVtables.blocks[i].start);
     126             :     }
     127        6343 :     return castProxyToInterface(pProxy);
     128             : }
     129             : 
     130        3676 : void CppInterfaceProxy::acquireProxy() SAL_THROW(())
     131             : {
     132        3676 :     if (1 == osl_atomic_increment( &nRef ))
     133             :     {
     134             :         // rebirth of proxy zombie
     135             :         // register at cpp env
     136          93 :         void * pThis = castProxyToInterface( this );
     137          93 :         (*pBridge->getCppEnv()->registerProxyInterface)(
     138             :             pBridge->getCppEnv(), &pThis, freeCppInterfaceProxy, oid.pData,
     139          93 :             pTypeDescr );
     140             :         OSL_ASSERT( pThis == castProxyToInterface( this ) );
     141             :     }
     142        3676 : }
     143             : 
     144       10019 : void CppInterfaceProxy::releaseProxy() SAL_THROW(())
     145             : {
     146       10019 :     if (! osl_atomic_decrement( &nRef )) // last release
     147             :     {
     148             :         // revoke from cpp env
     149        6436 :         (*pBridge->getCppEnv()->revokeInterface)(
     150        6436 :             pBridge->getCppEnv(), castProxyToInterface( this ) );
     151             :     }
     152       10019 : }
     153             : 
     154        6343 : CppInterfaceProxy::CppInterfaceProxy(
     155             :     bridges::cpp_uno::shared::Bridge * pBridge_, uno_Interface * pUnoI_,
     156             :     typelib_InterfaceTypeDescription * pTypeDescr_, OUString const & rOId_)
     157             :     SAL_THROW(())
     158             :     : nRef( 1 )
     159             :     , pBridge( pBridge_ )
     160             :     , pUnoI( pUnoI_ )
     161             :     , pTypeDescr( pTypeDescr_ )
     162        6343 :     , oid( rOId_ )
     163             : {
     164        6343 :     pBridge->acquire();
     165        6343 :     ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
     166        6343 :     (*pUnoI->acquire)( pUnoI );
     167        6343 :     (*pBridge->getUnoEnv()->registerInterface)(
     168             :         pBridge->getUnoEnv(), reinterpret_cast< void ** >( &pUnoI ), oid.pData,
     169        6343 :         pTypeDescr );
     170        6343 : }
     171             : 
     172        6343 : CppInterfaceProxy::~CppInterfaceProxy()
     173        6343 : {}
     174             : 
     175       12872 : com::sun::star::uno::XInterface * CppInterfaceProxy::castProxyToInterface(
     176             :     CppInterfaceProxy * pProxy)
     177             : {
     178             :     return reinterpret_cast< com::sun::star::uno::XInterface * >(
     179       12872 :         &pProxy->vtables);
     180             : }
     181             : 
     182       27546 : CppInterfaceProxy * CppInterfaceProxy::castInterfaceToProxy(void * pInterface)
     183             : {
     184             :     // pInterface == &pProxy->vtables (this emulated offsetof is not truly
     185             :     // portable):
     186       27546 :     char const * const base = reinterpret_cast< char const * >(16);
     187             :     std::ptrdiff_t const offset = reinterpret_cast< char const * >(
     188       27546 :         &reinterpret_cast< CppInterfaceProxy const * >(base)->vtables) - base;
     189             :     return reinterpret_cast< CppInterfaceProxy * >(
     190       27546 :         static_cast< char * >(pInterface) - offset);
     191             : }
     192             : 
     193             : } } }
     194             : 
     195             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10