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-27 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         257 : void dso_init(void) {
      47         257 :     if (!pInstance)
      48         257 :         pInstance = new bridges::cpp_uno::shared::VtableFactory();
      49         257 : }
      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          18 :     bridges::cpp_uno::shared::VtableFactory * operator()() {
      70          18 :         return pInstance;
      71             :     }
      72             : };
      73             : 
      74        1693 : bridges::cpp_uno::shared::VtableFactory * getVtableFactory() {
      75             :     return rtl_Instance<
      76             :         bridges::cpp_uno::shared::VtableFactory, InitVtableFactory,
      77             :         osl::MutexGuard, osl::GetGlobalMutex >::create(
      78        1693 :             InitVtableFactory(), osl::GetGlobalMutex());
      79             : }
      80             : 
      81             : }
      82             : 
      83             : namespace bridges { namespace cpp_uno { namespace shared {
      84             : 
      85        1693 : void freeCppInterfaceProxy(uno_ExtEnvironment * pEnv, void * pInterface)
      86             : {
      87             :     CppInterfaceProxy * pThis = CppInterfaceProxy::castInterfaceToProxy(
      88        1693 :         pInterface);
      89        1693 :     if (pEnv != pThis->pBridge->getCppEnv()) {
      90             :         OSL_ASSERT(false);
      91             :     }
      92             : 
      93        1693 :     (*pThis->pBridge->getUnoEnv()->revokeInterface)(
      94        1693 :         pThis->pBridge->getUnoEnv(), pThis->pUnoI );
      95        1693 :     (*pThis->pUnoI->release)( pThis->pUnoI );
      96             :     ::typelib_typedescription_release(
      97        1693 :         (typelib_TypeDescription *)pThis->pTypeDescr );
      98        1693 :     pThis->pBridge->release();
      99             : 
     100             : #if OSL_DEBUG_LEVEL > 1
     101             :     *(int *)pInterface = 0xdeadbabe;
     102             : #endif
     103        1693 :     pThis->~CppInterfaceProxy();
     104        1693 :     delete[] reinterpret_cast< char * >(pThis);
     105        1693 : }
     106             : 
     107        1693 : 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        1693 :         reinterpret_cast< typelib_TypeDescription ** >(&pTypeDescr));
     114             :     bridges::cpp_uno::shared::VtableFactory::Vtables aVtables(
     115        1693 :         getVtableFactory()->getVtables(pTypeDescr));
     116             :     bridges::cpp_uno::shared::GuardedArray< char > pMemory(
     117             :         new char[
     118             :             sizeof (CppInterfaceProxy)
     119        1693 :             + (aVtables.count - 1) * sizeof (void **)]);
     120        1693 :     new(pMemory.get()) CppInterfaceProxy(pBridge, pUnoI, pTypeDescr, rOId);
     121             :     CppInterfaceProxy * pProxy = reinterpret_cast< CppInterfaceProxy * >(
     122        1693 :         pMemory.release());
     123        3400 :     for (sal_Int32 i = 0; i < aVtables.count; ++i) {
     124             :         pProxy->vtables[i] = VtableFactory::mapBlockToVtable(
     125        1707 :             aVtables.blocks[i].start);
     126             :     }
     127        1693 :     return castProxyToInterface(pProxy);
     128             : }
     129             : 
     130         265 : void CppInterfaceProxy::acquireProxy() SAL_THROW(())
     131             : {
     132         265 :     if (1 == osl_atomic_increment( &nRef ))
     133             :     {
     134             :         // rebirth of proxy zombie
     135             :         // register at cpp env
     136          30 :         void * pThis = castProxyToInterface( this );
     137          30 :         (*pBridge->getCppEnv()->registerProxyInterface)(
     138             :             pBridge->getCppEnv(), &pThis, freeCppInterfaceProxy, oid.pData,
     139          30 :             pTypeDescr );
     140             :         OSL_ASSERT( pThis == castProxyToInterface( this ) );
     141             :     }
     142         265 : }
     143             : 
     144        1958 : void CppInterfaceProxy::releaseProxy() SAL_THROW(())
     145             : {
     146        1958 :     if (! osl_atomic_decrement( &nRef )) // last release
     147             :     {
     148             :         // revoke from cpp env
     149        1723 :         (*pBridge->getCppEnv()->revokeInterface)(
     150        1723 :             pBridge->getCppEnv(), castProxyToInterface( this ) );
     151             :     }
     152        1958 : }
     153             : 
     154        1693 : 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        1693 :     , oid( rOId_ )
     163             : {
     164        1693 :     pBridge->acquire();
     165        1693 :     ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
     166        1693 :     (*pUnoI->acquire)( pUnoI );
     167        1693 :     (*pBridge->getUnoEnv()->registerInterface)(
     168             :         pBridge->getUnoEnv(), reinterpret_cast< void ** >( &pUnoI ), oid.pData,
     169        1693 :         pTypeDescr );
     170        1693 : }
     171             : 
     172        1693 : CppInterfaceProxy::~CppInterfaceProxy()
     173        1693 : {}
     174             : 
     175        3446 : com::sun::star::uno::XInterface * CppInterfaceProxy::castProxyToInterface(
     176             :     CppInterfaceProxy * pProxy)
     177             : {
     178             :     return reinterpret_cast< com::sun::star::uno::XInterface * >(
     179        3446 :         &pProxy->vtables);
     180             : }
     181             : 
     182        5976 : CppInterfaceProxy * CppInterfaceProxy::castInterfaceToProxy(void * pInterface)
     183             : {
     184             :     // pInterface == &pProxy->vtables (this emulated offsetof is not truly
     185             :     // portable):
     186        5976 :     char const * const base = reinterpret_cast< char const * >(16);
     187             :     std::ptrdiff_t const offset = reinterpret_cast< char const * >(
     188        5976 :         &reinterpret_cast< CppInterfaceProxy const * >(base)->vtables) - base;
     189             :     return reinterpret_cast< CppInterfaceProxy * >(
     190        5976 :         static_cast< char * >(pInterface) - offset);
     191             : }
     192             : 
     193             : } } }
     194             : 
     195             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10