1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir 29*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 30*cdf0e10cSrcweir #include "precompiled_bridges.hxx" 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include "guardedarray.hxx" 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/bridge.hxx" 37*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/vtablefactory.hxx" 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp" 40*cdf0e10cSrcweir #include "osl/diagnose.h" 41*cdf0e10cSrcweir #include "osl/getglobalmutex.hxx" 42*cdf0e10cSrcweir #include "osl/interlck.h" 43*cdf0e10cSrcweir #include "osl/mutex.hxx" 44*cdf0e10cSrcweir #include "rtl/instance.hxx" 45*cdf0e10cSrcweir #include "typelib/typedescription.h" 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #include <cstddef> 48*cdf0e10cSrcweir #include <new> 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir static bridges::cpp_uno::shared::VtableFactory * pInstance; 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir #if defined(__GNUG__) && !defined(__MINGW32__) 54*cdf0e10cSrcweir void dso_init(void) __attribute__((constructor)); 55*cdf0e10cSrcweir void dso_exit(void) __attribute__((destructor)); 56*cdf0e10cSrcweir #endif 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir void dso_init(void) { 59*cdf0e10cSrcweir if (!pInstance) 60*cdf0e10cSrcweir pInstance = new bridges::cpp_uno::shared::VtableFactory(); 61*cdf0e10cSrcweir } 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir void dso_exit(void) { 64*cdf0e10cSrcweir if (pInstance) 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir delete pInstance; 67*cdf0e10cSrcweir pInstance = NULL; 68*cdf0e10cSrcweir } 69*cdf0e10cSrcweir } 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir #ifdef __SUNPRO_CC 72*cdf0e10cSrcweir # pragma init(dso_init) 73*cdf0e10cSrcweir # pragma fini(dso_exit) 74*cdf0e10cSrcweir #endif 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir namespace { 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir struct InitVtableFactory { 81*cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory * operator()() { 82*cdf0e10cSrcweir return pInstance; 83*cdf0e10cSrcweir } 84*cdf0e10cSrcweir }; 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory * getVtableFactory() { 87*cdf0e10cSrcweir return rtl_Instance< 88*cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory, InitVtableFactory, 89*cdf0e10cSrcweir osl::MutexGuard, osl::GetGlobalMutex >::create( 90*cdf0e10cSrcweir InitVtableFactory(), osl::GetGlobalMutex()); 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir } 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir namespace bridges { namespace cpp_uno { namespace shared { 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir void freeCppInterfaceProxy(uno_ExtEnvironment * pEnv, void * pInterface) 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir CppInterfaceProxy * pThis = CppInterfaceProxy::castInterfaceToProxy( 100*cdf0e10cSrcweir pInterface); 101*cdf0e10cSrcweir if (pEnv != pThis->pBridge->getCppEnv()) { 102*cdf0e10cSrcweir OSL_ASSERT(false); 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir (*pThis->pBridge->getUnoEnv()->revokeInterface)( 106*cdf0e10cSrcweir pThis->pBridge->getUnoEnv(), pThis->pUnoI ); 107*cdf0e10cSrcweir (*pThis->pUnoI->release)( pThis->pUnoI ); 108*cdf0e10cSrcweir ::typelib_typedescription_release( 109*cdf0e10cSrcweir (typelib_TypeDescription *)pThis->pTypeDescr ); 110*cdf0e10cSrcweir pThis->pBridge->release(); 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 113*cdf0e10cSrcweir *(int *)pInterface = 0xdeadbabe; 114*cdf0e10cSrcweir #endif 115*cdf0e10cSrcweir pThis->~CppInterfaceProxy(); 116*cdf0e10cSrcweir delete[] reinterpret_cast< char * >(pThis); 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir com::sun::star::uno::XInterface * CppInterfaceProxy::create( 120*cdf0e10cSrcweir bridges::cpp_uno::shared::Bridge * pBridge, uno_Interface * pUnoI, 121*cdf0e10cSrcweir typelib_InterfaceTypeDescription * pTypeDescr, rtl::OUString const & rOId) 122*cdf0e10cSrcweir SAL_THROW(()) 123*cdf0e10cSrcweir { 124*cdf0e10cSrcweir typelib_typedescription_complete( 125*cdf0e10cSrcweir reinterpret_cast< typelib_TypeDescription ** >(&pTypeDescr)); 126*cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory::Vtables aVtables( 127*cdf0e10cSrcweir getVtableFactory()->getVtables(pTypeDescr)); 128*cdf0e10cSrcweir bridges::cpp_uno::shared::GuardedArray< char > pMemory( 129*cdf0e10cSrcweir new char[ 130*cdf0e10cSrcweir sizeof (CppInterfaceProxy) 131*cdf0e10cSrcweir + (aVtables.count - 1) * sizeof (void **)]); 132*cdf0e10cSrcweir new(pMemory.get()) CppInterfaceProxy(pBridge, pUnoI, pTypeDescr, rOId); 133*cdf0e10cSrcweir CppInterfaceProxy * pProxy = reinterpret_cast< CppInterfaceProxy * >( 134*cdf0e10cSrcweir pMemory.release()); 135*cdf0e10cSrcweir for (sal_Int32 i = 0; i < aVtables.count; ++i) { 136*cdf0e10cSrcweir pProxy->vtables[i] = VtableFactory::mapBlockToVtable( 137*cdf0e10cSrcweir aVtables.blocks[i].start); 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir return castProxyToInterface(pProxy); 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir void CppInterfaceProxy::acquireProxy() SAL_THROW(()) 143*cdf0e10cSrcweir { 144*cdf0e10cSrcweir if (1 == osl_incrementInterlockedCount( &nRef )) 145*cdf0e10cSrcweir { 146*cdf0e10cSrcweir // rebirth of proxy zombie 147*cdf0e10cSrcweir // register at cpp env 148*cdf0e10cSrcweir void * pThis = castProxyToInterface( this ); 149*cdf0e10cSrcweir (*pBridge->getCppEnv()->registerProxyInterface)( 150*cdf0e10cSrcweir pBridge->getCppEnv(), &pThis, freeCppInterfaceProxy, oid.pData, 151*cdf0e10cSrcweir pTypeDescr ); 152*cdf0e10cSrcweir OSL_ASSERT( pThis == castProxyToInterface( this ) ); 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir void CppInterfaceProxy::releaseProxy() SAL_THROW(()) 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir if (! osl_decrementInterlockedCount( &nRef )) // last release 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir // revoke from cpp env 161*cdf0e10cSrcweir (*pBridge->getCppEnv()->revokeInterface)( 162*cdf0e10cSrcweir pBridge->getCppEnv(), castProxyToInterface( this ) ); 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir CppInterfaceProxy::CppInterfaceProxy( 167*cdf0e10cSrcweir bridges::cpp_uno::shared::Bridge * pBridge_, uno_Interface * pUnoI_, 168*cdf0e10cSrcweir typelib_InterfaceTypeDescription * pTypeDescr_, rtl::OUString const & rOId_) 169*cdf0e10cSrcweir SAL_THROW(()) 170*cdf0e10cSrcweir : nRef( 1 ) 171*cdf0e10cSrcweir , pBridge( pBridge_ ) 172*cdf0e10cSrcweir , pUnoI( pUnoI_ ) 173*cdf0e10cSrcweir , pTypeDescr( pTypeDescr_ ) 174*cdf0e10cSrcweir , oid( rOId_ ) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir pBridge->acquire(); 177*cdf0e10cSrcweir ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr ); 178*cdf0e10cSrcweir (*pUnoI->acquire)( pUnoI ); 179*cdf0e10cSrcweir (*pBridge->getUnoEnv()->registerInterface)( 180*cdf0e10cSrcweir pBridge->getUnoEnv(), reinterpret_cast< void ** >( &pUnoI ), oid.pData, 181*cdf0e10cSrcweir pTypeDescr ); 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir CppInterfaceProxy::~CppInterfaceProxy() 185*cdf0e10cSrcweir {} 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir com::sun::star::uno::XInterface * CppInterfaceProxy::castProxyToInterface( 188*cdf0e10cSrcweir CppInterfaceProxy * pProxy) 189*cdf0e10cSrcweir { 190*cdf0e10cSrcweir return reinterpret_cast< com::sun::star::uno::XInterface * >( 191*cdf0e10cSrcweir &pProxy->vtables); 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir CppInterfaceProxy * CppInterfaceProxy::castInterfaceToProxy(void * pInterface) 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir // pInterface == &pProxy->vtables (this emulated offsetof is not truly 197*cdf0e10cSrcweir // portable): 198*cdf0e10cSrcweir char const * const base = reinterpret_cast< char const * >(16); 199*cdf0e10cSrcweir std::ptrdiff_t const offset = reinterpret_cast< char const * >( 200*cdf0e10cSrcweir &reinterpret_cast< CppInterfaceProxy const * >(base)->vtables) - base; 201*cdf0e10cSrcweir return reinterpret_cast< CppInterfaceProxy * >( 202*cdf0e10cSrcweir static_cast< char * >(pInterface) - offset); 203*cdf0e10cSrcweir } 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir } } } 206