Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / cppu / source / threadpool / current.cxx
blob227a9ab0abb04587d633ff8b270bd96c78b181fc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "rtl/uuid.h"
22 #include "osl/thread.h"
23 #include "osl/mutex.hxx"
25 #include "uno/environment.hxx"
26 #include "uno/mapping.hxx"
27 #include "uno/lbnames.h"
28 #include "typelib/typedescription.h"
30 #include "current.hxx"
33 using namespace ::osl;
34 using namespace ::rtl;
35 using namespace ::cppu;
36 using namespace ::com::sun::star::uno;
38 namespace cppu
41 static typelib_InterfaceTypeDescription * get_type_XCurrentContext()
43 static typelib_InterfaceTypeDescription * s_type_XCurrentContext = 0;
44 if (0 == s_type_XCurrentContext)
46 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
47 if (0 == s_type_XCurrentContext)
49 OUString sTypeName("com.sun.star.uno.XCurrentContext");
50 typelib_InterfaceTypeDescription * pTD = 0;
51 typelib_TypeDescriptionReference * pMembers[1] = { 0 };
52 OUString sMethodName0("com.sun.star.uno.XCurrentContext::getValueByName");
53 typelib_typedescriptionreference_new(
54 &pMembers[0],
55 typelib_TypeClass_INTERFACE_METHOD,
56 sMethodName0.pData );
57 typelib_typedescription_newInterface(
58 &pTD,
59 sTypeName.pData, 0, 0, 0, 0, 0,
60 * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ),
62 pMembers );
64 typelib_typedescription_register( (typelib_TypeDescription**)&pTD );
65 typelib_typedescriptionreference_release( pMembers[0] );
67 typelib_InterfaceMethodTypeDescription * pMethod = 0;
68 typelib_Parameter_Init aParameters[1];
69 OUString sParamName0("Name");
70 OUString sParamType0("string");
71 aParameters[0].pParamName = sParamName0.pData;
72 aParameters[0].eTypeClass = typelib_TypeClass_STRING;
73 aParameters[0].pTypeName = sParamType0.pData;
74 aParameters[0].bIn = sal_True;
75 aParameters[0].bOut = sal_False;
76 rtl_uString * pExceptions[1];
77 OUString sExceptionName0("com.sun.star.uno.RuntimeException");
78 pExceptions[0] = sExceptionName0.pData;
79 OUString sReturnType0("any");
80 typelib_typedescription_newInterfaceMethod(
81 &pMethod,
82 3, sal_False,
83 sMethodName0.pData,
84 typelib_TypeClass_ANY, sReturnType0.pData,
85 1, aParameters, 1, pExceptions );
86 typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
87 typelib_typedescription_release( (typelib_TypeDescription*)pMethod );
88 // another static ref:
89 ++reinterpret_cast< typelib_TypeDescription * >( pTD )->
90 nStaticRefCount;
91 s_type_XCurrentContext = pTD;
94 return s_type_XCurrentContext;
97 //##################################################################################################
99 //==================================================================================================
100 class ThreadKey
102 sal_Bool _bInit;
103 oslThreadKey _hThreadKey;
104 oslThreadKeyCallbackFunction _pCallback;
106 public:
107 inline oslThreadKey getThreadKey() SAL_THROW(());
109 inline ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW(());
110 inline ~ThreadKey() SAL_THROW(());
112 //__________________________________________________________________________________________________
113 inline ThreadKey::ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW(())
114 : _bInit( sal_False )
115 , _pCallback( pCallback )
118 //__________________________________________________________________________________________________
119 inline ThreadKey::~ThreadKey() SAL_THROW(())
121 if (_bInit)
123 ::osl_destroyThreadKey( _hThreadKey );
126 //__________________________________________________________________________________________________
127 inline oslThreadKey ThreadKey::getThreadKey() SAL_THROW(())
129 if (! _bInit)
131 MutexGuard aGuard( Mutex::getGlobalMutex() );
132 if (! _bInit)
134 _hThreadKey = ::osl_createThreadKey( _pCallback );
135 _bInit = sal_True;
138 return _hThreadKey;
141 //==================================================================================================
142 extern "C" void SAL_CALL delete_IdContainer( void * p )
144 if (p)
146 IdContainer * pId = reinterpret_cast< IdContainer * >( p );
147 if (pId->pCurrentContext)
149 (*pId->pCurrentContextEnv->releaseInterface)(
150 pId->pCurrentContextEnv, pId->pCurrentContext );
151 (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
152 (uno_Environment *)pId->pCurrentContextEnv );
154 if (pId->bInit)
156 ::rtl_byte_sequence_release( pId->pLocalThreadId );
157 ::rtl_byte_sequence_release( pId->pCurrentId );
159 delete pId;
162 //==================================================================================================
163 IdContainer * getIdContainer() SAL_THROW(())
165 static ThreadKey s_key( delete_IdContainer );
166 oslThreadKey aKey = s_key.getThreadKey();
168 IdContainer * pId = reinterpret_cast< IdContainer * >( ::osl_getThreadKeyData( aKey ) );
169 if (! pId)
171 pId = new IdContainer();
172 pId->pCurrentContext = 0;
173 pId->pCurrentContextEnv = 0;
174 pId->bInit = sal_False;
175 ::osl_setThreadKeyData( aKey, pId );
177 return pId;
182 //##################################################################################################
183 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL uno_setCurrentContext(
184 void * pCurrentContext,
185 rtl_uString * pEnvTypeName, void * pEnvContext )
186 SAL_THROW_EXTERN_C()
188 IdContainer * pId = getIdContainer();
189 OSL_ASSERT( pId );
191 // free old one
192 if (pId->pCurrentContext)
194 (*pId->pCurrentContextEnv->releaseInterface)(
195 pId->pCurrentContextEnv, pId->pCurrentContext );
196 (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
197 (uno_Environment *)pId->pCurrentContextEnv );
198 pId->pCurrentContextEnv = 0;
200 pId->pCurrentContext = 0;
203 if (pCurrentContext)
205 uno_Environment * pEnv = 0;
206 ::uno_getEnvironment( &pEnv, pEnvTypeName, pEnvContext );
207 OSL_ASSERT( pEnv && pEnv->pExtEnv );
208 if (pEnv)
210 if (pEnv->pExtEnv)
212 pId->pCurrentContextEnv = pEnv->pExtEnv;
213 (*pId->pCurrentContextEnv->acquireInterface)(
214 pId->pCurrentContextEnv, pCurrentContext );
215 pId->pCurrentContext = pCurrentContext;
217 else
219 (*pEnv->release)( pEnv );
220 return sal_False;
223 else
225 return sal_False;
228 return sal_True;
230 //##################################################################################################
231 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL uno_getCurrentContext(
232 void ** ppCurrentContext, rtl_uString * pEnvTypeName, void * pEnvContext )
233 SAL_THROW_EXTERN_C()
235 IdContainer * pId = getIdContainer();
236 OSL_ASSERT( pId );
238 Environment target_env;
240 // release inout parameter
241 if (*ppCurrentContext)
243 target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
244 OSL_ASSERT( target_env.is() );
245 if (! target_env.is())
246 return sal_False;
247 uno_ExtEnvironment * pEnv = target_env.get()->pExtEnv;
248 OSL_ASSERT( 0 != pEnv );
249 if (0 == pEnv)
250 return sal_False;
251 (*pEnv->releaseInterface)( pEnv, *ppCurrentContext );
253 *ppCurrentContext = 0;
256 // case: null-ref
257 if (0 == pId->pCurrentContext)
258 return sal_True;
260 if (! target_env.is())
262 target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
263 OSL_ASSERT( target_env.is() );
264 if (! target_env.is())
265 return sal_False;
268 Mapping mapping((uno_Environment *) pId->pCurrentContextEnv, target_env.get());
269 OSL_ASSERT( mapping.is() );
270 if (! mapping.is())
271 return sal_False;
273 mapping.mapInterface(ppCurrentContext, pId->pCurrentContext, ::cppu::get_type_XCurrentContext() );
275 return sal_True;
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */