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