xref: /aoo42x/main/cppu/source/threadpool/current.cxx (revision 129fa3d1)
1*129fa3d1SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*129fa3d1SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*129fa3d1SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*129fa3d1SAndrew Rist  * distributed with this work for additional information
6*129fa3d1SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*129fa3d1SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*129fa3d1SAndrew Rist  * "License"); you may not use this file except in compliance
9*129fa3d1SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*129fa3d1SAndrew Rist  *
11*129fa3d1SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*129fa3d1SAndrew Rist  *
13*129fa3d1SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*129fa3d1SAndrew Rist  * software distributed under the License is distributed on an
15*129fa3d1SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*129fa3d1SAndrew Rist  * KIND, either express or implied.  See the License for the
17*129fa3d1SAndrew Rist  * specific language governing permissions and limitations
18*129fa3d1SAndrew Rist  * under the License.
19*129fa3d1SAndrew Rist  *
20*129fa3d1SAndrew Rist  *************************************************************/
21*129fa3d1SAndrew Rist 
22*129fa3d1SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_cppu.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "rtl/uuid.h"
28cdf0e10cSrcweir #include "osl/thread.h"
29cdf0e10cSrcweir #include "osl/mutex.hxx"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "uno/environment.hxx"
32cdf0e10cSrcweir #include "uno/mapping.hxx"
33cdf0e10cSrcweir #include "uno/lbnames.h"
34cdf0e10cSrcweir #include "typelib/typedescription.h"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include "current.hxx"
37cdf0e10cSrcweir 
38cdf0e10cSrcweir 
39cdf0e10cSrcweir using namespace ::osl;
40cdf0e10cSrcweir using namespace ::rtl;
41cdf0e10cSrcweir using namespace ::cppu;
42cdf0e10cSrcweir using namespace ::com::sun::star::uno;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir namespace cppu
45cdf0e10cSrcweir {
46cdf0e10cSrcweir 
47cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
48cdf0e10cSrcweir class SAL_NO_VTABLE XInterface
49cdf0e10cSrcweir {
50cdf0e10cSrcweir public:
51cdf0e10cSrcweir     virtual void SAL_CALL slot_queryInterface() = 0;
52cdf0e10cSrcweir     virtual void SAL_CALL acquire() throw () = 0;
53cdf0e10cSrcweir     virtual void SAL_CALL release() throw () = 0;
54cdf0e10cSrcweir };
55cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
get_type_XCurrentContext()56cdf0e10cSrcweir static typelib_InterfaceTypeDescription * get_type_XCurrentContext()
57cdf0e10cSrcweir {
58cdf0e10cSrcweir     static typelib_InterfaceTypeDescription * s_type_XCurrentContext = 0;
59cdf0e10cSrcweir     if (0 == s_type_XCurrentContext)
60cdf0e10cSrcweir     {
61cdf0e10cSrcweir         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
62cdf0e10cSrcweir         if (0 == s_type_XCurrentContext)
63cdf0e10cSrcweir         {
64cdf0e10cSrcweir             OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XCurrentContext") );
65cdf0e10cSrcweir             typelib_InterfaceTypeDescription * pTD = 0;
66cdf0e10cSrcweir             typelib_TypeDescriptionReference * pMembers[1] = { 0 };
67cdf0e10cSrcweir             OUString sMethodName0(
68cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XCurrentContext::getValueByName") );
69cdf0e10cSrcweir             typelib_typedescriptionreference_new(
70cdf0e10cSrcweir                 &pMembers[0],
71cdf0e10cSrcweir                 typelib_TypeClass_INTERFACE_METHOD,
72cdf0e10cSrcweir                 sMethodName0.pData );
73cdf0e10cSrcweir             typelib_typedescription_newInterface(
74cdf0e10cSrcweir                 &pTD,
75cdf0e10cSrcweir                 sTypeName.pData, 0x00000000, 0x0000, 0x0000, 0x00000000, 0x00000000,
76cdf0e10cSrcweir                 * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ),
77cdf0e10cSrcweir                 1,
78cdf0e10cSrcweir                 pMembers );
79cdf0e10cSrcweir 
80cdf0e10cSrcweir             typelib_typedescription_register( (typelib_TypeDescription**)&pTD );
81cdf0e10cSrcweir             typelib_typedescriptionreference_release( pMembers[0] );
82cdf0e10cSrcweir 
83cdf0e10cSrcweir             typelib_InterfaceMethodTypeDescription * pMethod = 0;
84cdf0e10cSrcweir             typelib_Parameter_Init aParameters[1];
85cdf0e10cSrcweir             OUString sParamName0( RTL_CONSTASCII_USTRINGPARAM("Name") );
86cdf0e10cSrcweir             OUString sParamType0( RTL_CONSTASCII_USTRINGPARAM("string") );
87cdf0e10cSrcweir             aParameters[0].pParamName = sParamName0.pData;
88cdf0e10cSrcweir             aParameters[0].eTypeClass = typelib_TypeClass_STRING;
89cdf0e10cSrcweir             aParameters[0].pTypeName = sParamType0.pData;
90cdf0e10cSrcweir             aParameters[0].bIn = sal_True;
91cdf0e10cSrcweir             aParameters[0].bOut = sal_False;
92cdf0e10cSrcweir             rtl_uString * pExceptions[1];
93cdf0e10cSrcweir             OUString sExceptionName0(
94cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") );
95cdf0e10cSrcweir             pExceptions[0] = sExceptionName0.pData;
96cdf0e10cSrcweir             OUString sReturnType0( RTL_CONSTASCII_USTRINGPARAM("any") );
97cdf0e10cSrcweir             typelib_typedescription_newInterfaceMethod(
98cdf0e10cSrcweir                 &pMethod,
99cdf0e10cSrcweir                 3, sal_False,
100cdf0e10cSrcweir                 sMethodName0.pData,
101cdf0e10cSrcweir                 typelib_TypeClass_ANY, sReturnType0.pData,
102cdf0e10cSrcweir                 1, aParameters, 1, pExceptions );
103cdf0e10cSrcweir             typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
104cdf0e10cSrcweir             typelib_typedescription_release( (typelib_TypeDescription*)pMethod );
105cdf0e10cSrcweir             // another static ref:
106cdf0e10cSrcweir             ++reinterpret_cast< typelib_TypeDescription * >( pTD )->
107cdf0e10cSrcweir                 nStaticRefCount;
108cdf0e10cSrcweir             s_type_XCurrentContext = pTD;
109cdf0e10cSrcweir         }
110cdf0e10cSrcweir     }
111cdf0e10cSrcweir     return s_type_XCurrentContext;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir //##################################################################################################
115cdf0e10cSrcweir 
116cdf0e10cSrcweir //==================================================================================================
117cdf0e10cSrcweir class ThreadKey
118cdf0e10cSrcweir {
119cdf0e10cSrcweir 	sal_Bool	 _bInit;
120cdf0e10cSrcweir 	oslThreadKey _hThreadKey;
121cdf0e10cSrcweir 	oslThreadKeyCallbackFunction _pCallback;
122cdf0e10cSrcweir 
123cdf0e10cSrcweir public:
124cdf0e10cSrcweir 	inline oslThreadKey getThreadKey() SAL_THROW( () );
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 	inline ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW( () );
127cdf0e10cSrcweir 	inline ~ThreadKey() SAL_THROW( () );
128cdf0e10cSrcweir };
129cdf0e10cSrcweir //__________________________________________________________________________________________________
ThreadKey(oslThreadKeyCallbackFunction pCallback)130cdf0e10cSrcweir inline ThreadKey::ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW( () )
131cdf0e10cSrcweir 	: _bInit( sal_False )
132cdf0e10cSrcweir 	, _pCallback( pCallback )
133cdf0e10cSrcweir {
134cdf0e10cSrcweir }
135cdf0e10cSrcweir //__________________________________________________________________________________________________
~ThreadKey()136cdf0e10cSrcweir inline ThreadKey::~ThreadKey() SAL_THROW( () )
137cdf0e10cSrcweir {
138cdf0e10cSrcweir 	if (_bInit)
139cdf0e10cSrcweir 	{
140cdf0e10cSrcweir 		::osl_destroyThreadKey( _hThreadKey );
141cdf0e10cSrcweir 	}
142cdf0e10cSrcweir }
143cdf0e10cSrcweir //__________________________________________________________________________________________________
getThreadKey()144cdf0e10cSrcweir inline oslThreadKey ThreadKey::getThreadKey() SAL_THROW( () )
145cdf0e10cSrcweir {
146cdf0e10cSrcweir 	if (! _bInit)
147cdf0e10cSrcweir 	{
148cdf0e10cSrcweir 		MutexGuard aGuard( Mutex::getGlobalMutex() );
149cdf0e10cSrcweir 		if (! _bInit)
150cdf0e10cSrcweir 		{
151cdf0e10cSrcweir 			_hThreadKey = ::osl_createThreadKey( _pCallback );
152cdf0e10cSrcweir 			_bInit = sal_True;
153cdf0e10cSrcweir 		}
154cdf0e10cSrcweir 	}
155cdf0e10cSrcweir 	return _hThreadKey;
156cdf0e10cSrcweir }
157cdf0e10cSrcweir 
158cdf0e10cSrcweir //==================================================================================================
delete_IdContainer(void * p)159cdf0e10cSrcweir extern "C" void SAL_CALL delete_IdContainer( void * p )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir 	if (p)
162cdf0e10cSrcweir 	{
163cdf0e10cSrcweir 		IdContainer * pId = reinterpret_cast< IdContainer * >( p );
164cdf0e10cSrcweir 		if (pId->pCurrentContext)
165cdf0e10cSrcweir 		{
166cdf0e10cSrcweir             (*pId->pCurrentContextEnv->releaseInterface)(
167cdf0e10cSrcweir                 pId->pCurrentContextEnv, pId->pCurrentContext );
168cdf0e10cSrcweir             (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
169cdf0e10cSrcweir                 (uno_Environment *)pId->pCurrentContextEnv );
170cdf0e10cSrcweir 		}
171cdf0e10cSrcweir 		if (pId->bInit)
172cdf0e10cSrcweir 		{
173cdf0e10cSrcweir 			::rtl_byte_sequence_release( pId->pLocalThreadId );
174cdf0e10cSrcweir 			::rtl_byte_sequence_release( pId->pCurrentId );
175cdf0e10cSrcweir 		}
176cdf0e10cSrcweir 		delete pId;
177cdf0e10cSrcweir 	}
178cdf0e10cSrcweir }
179cdf0e10cSrcweir //==================================================================================================
getIdContainer()180cdf0e10cSrcweir IdContainer * getIdContainer() SAL_THROW( () )
181cdf0e10cSrcweir {
182cdf0e10cSrcweir 	static ThreadKey s_key( delete_IdContainer );
183cdf0e10cSrcweir 	oslThreadKey aKey = s_key.getThreadKey();
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 	IdContainer * pId = reinterpret_cast< IdContainer * >( ::osl_getThreadKeyData( aKey ) );
186cdf0e10cSrcweir 	if (! pId)
187cdf0e10cSrcweir 	{
188cdf0e10cSrcweir 		pId = new IdContainer();
189cdf0e10cSrcweir 		pId->pCurrentContext = 0;
190cdf0e10cSrcweir         pId->pCurrentContextEnv = 0;
191cdf0e10cSrcweir 		pId->bInit = sal_False;
192cdf0e10cSrcweir 		::osl_setThreadKeyData( aKey, pId );
193cdf0e10cSrcweir 	}
194cdf0e10cSrcweir 	return pId;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
199cdf0e10cSrcweir //##################################################################################################
uno_setCurrentContext(void * pCurrentContext,rtl_uString * pEnvTypeName,void * pEnvContext)200cdf0e10cSrcweir extern "C" sal_Bool SAL_CALL uno_setCurrentContext(
201cdf0e10cSrcweir 	void * pCurrentContext,
202cdf0e10cSrcweir 	rtl_uString * pEnvTypeName, void * pEnvContext )
203cdf0e10cSrcweir 	SAL_THROW_EXTERN_C()
204cdf0e10cSrcweir {
205cdf0e10cSrcweir     IdContainer * pId = getIdContainer();
206cdf0e10cSrcweir     OSL_ASSERT( pId );
207cdf0e10cSrcweir 
208cdf0e10cSrcweir     // free old one
209cdf0e10cSrcweir     if (pId->pCurrentContext)
210cdf0e10cSrcweir     {
211cdf0e10cSrcweir         (*pId->pCurrentContextEnv->releaseInterface)(
212cdf0e10cSrcweir             pId->pCurrentContextEnv, pId->pCurrentContext );
213cdf0e10cSrcweir         (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
214cdf0e10cSrcweir             (uno_Environment *)pId->pCurrentContextEnv );
215cdf0e10cSrcweir         pId->pCurrentContextEnv = 0;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir         pId->pCurrentContext = 0;
218cdf0e10cSrcweir     }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir     if (pCurrentContext)
221cdf0e10cSrcweir     {
222cdf0e10cSrcweir         uno_Environment * pEnv = 0;
223cdf0e10cSrcweir         ::uno_getEnvironment( &pEnv, pEnvTypeName, pEnvContext );
224cdf0e10cSrcweir         OSL_ASSERT( pEnv && pEnv->pExtEnv );
225cdf0e10cSrcweir         if (pEnv)
226cdf0e10cSrcweir         {
227cdf0e10cSrcweir             if (pEnv->pExtEnv)
228cdf0e10cSrcweir             {
229cdf0e10cSrcweir                 pId->pCurrentContextEnv = pEnv->pExtEnv;
230cdf0e10cSrcweir                 (*pId->pCurrentContextEnv->acquireInterface)(
231cdf0e10cSrcweir                     pId->pCurrentContextEnv, pCurrentContext );
232cdf0e10cSrcweir                 pId->pCurrentContext = pCurrentContext;
233cdf0e10cSrcweir             }
234cdf0e10cSrcweir             else
235cdf0e10cSrcweir             {
236cdf0e10cSrcweir                 (*pEnv->release)( pEnv );
237cdf0e10cSrcweir                 return sal_False;
238cdf0e10cSrcweir             }
239cdf0e10cSrcweir         }
240cdf0e10cSrcweir         else
241cdf0e10cSrcweir         {
242cdf0e10cSrcweir             return sal_False;
243cdf0e10cSrcweir         }
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir     return sal_True;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir //##################################################################################################
uno_getCurrentContext(void ** ppCurrentContext,rtl_uString * pEnvTypeName,void * pEnvContext)248cdf0e10cSrcweir extern "C" sal_Bool SAL_CALL uno_getCurrentContext(
249cdf0e10cSrcweir 	void ** ppCurrentContext, rtl_uString * pEnvTypeName, void * pEnvContext )
250cdf0e10cSrcweir 	SAL_THROW_EXTERN_C()
251cdf0e10cSrcweir {
252cdf0e10cSrcweir     IdContainer * pId = getIdContainer();
253cdf0e10cSrcweir     OSL_ASSERT( pId );
254cdf0e10cSrcweir 
255cdf0e10cSrcweir     Environment target_env;
256cdf0e10cSrcweir 
257cdf0e10cSrcweir     // release inout parameter
258cdf0e10cSrcweir     if (*ppCurrentContext)
259cdf0e10cSrcweir     {
260cdf0e10cSrcweir         target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
261cdf0e10cSrcweir         OSL_ASSERT( target_env.is() );
262cdf0e10cSrcweir         if (! target_env.is())
263cdf0e10cSrcweir             return sal_False;
264cdf0e10cSrcweir         uno_ExtEnvironment * pEnv = target_env.get()->pExtEnv;
265cdf0e10cSrcweir         OSL_ASSERT( 0 != pEnv );
266cdf0e10cSrcweir         if (0 == pEnv)
267cdf0e10cSrcweir             return sal_False;
268cdf0e10cSrcweir         (*pEnv->releaseInterface)( pEnv, *ppCurrentContext );
269cdf0e10cSrcweir 
270cdf0e10cSrcweir         *ppCurrentContext = 0;
271cdf0e10cSrcweir     }
272cdf0e10cSrcweir 
273cdf0e10cSrcweir     // case: null-ref
274cdf0e10cSrcweir     if (0 == pId->pCurrentContext)
275cdf0e10cSrcweir         return sal_True;
276cdf0e10cSrcweir 
277cdf0e10cSrcweir     if (! target_env.is())
278cdf0e10cSrcweir     {
279cdf0e10cSrcweir         target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
280cdf0e10cSrcweir         OSL_ASSERT( target_env.is() );
281cdf0e10cSrcweir         if (! target_env.is())
282cdf0e10cSrcweir             return sal_False;
283cdf0e10cSrcweir     }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir     Mapping mapping((uno_Environment *) pId->pCurrentContextEnv, target_env.get());
286cdf0e10cSrcweir     OSL_ASSERT( mapping.is() );
287cdf0e10cSrcweir     if (! mapping.is())
288cdf0e10cSrcweir         return sal_False;
289cdf0e10cSrcweir 
290cdf0e10cSrcweir     mapping.mapInterface(ppCurrentContext, pId->pCurrentContext, ::cppu::get_type_XCurrentContext() );
291cdf0e10cSrcweir 
292cdf0e10cSrcweir     return sal_True;
293cdf0e10cSrcweir }
294