Bug Summary

File:cppu/source/uno/lbenv.cxx
Location:line 317, column 32
Description:Dereference of null pointer (loaded from variable 'ppInterface')

Annotated 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
21#include "cppu/EnvDcp.hxx"
22
23#include "sal/alloca.h"
24#include "sal/log.hxx"
25#include "osl/diagnose.h"
26#include "osl/interlck.h"
27#include "osl/mutex.hxx"
28#include "osl/module.h"
29#include "osl/process.h"
30#include "rtl/process.h"
31#include "rtl/unload.h"
32#include "rtl/string.hxx"
33#include "rtl/ustring.hxx"
34#include "rtl/ustrbuf.hxx"
35#include "rtl/instance.hxx"
36#include "typelib/typedescription.h"
37#include "uno/dispatcher.h"
38#include "uno/environment.h"
39#include "uno/lbnames.h"
40#include "prim.hxx"
41#include "destr.hxx"
42#include "loadmodule.hxx"
43
44#include <boost/unordered_map.hpp>
45#include <vector>
46#include <stdio.h>
47
48
49using ::rtl::OUString;
50
51namespace
52{
53
54//------------------------------------------------------------------------------
55inline static bool td_equals( typelib_InterfaceTypeDescription * pTD1,
56 typelib_InterfaceTypeDescription * pTD2 )
57{
58 return (pTD1 == pTD2 ||
59 (((typelib_TypeDescription *)pTD1)->pTypeName->length ==
60 ((typelib_TypeDescription *)pTD2)->pTypeName->length &&
61 ::rtl_ustr_compare(
62 ((typelib_TypeDescription *) pTD1)->pTypeName->buffer,
63 ((typelib_TypeDescription *) pTD2)->pTypeName->buffer ) == 0));
64}
65
66struct ObjectEntry;
67struct uno_DefaultEnvironment;
68
69//------------------------------------------------------------------------------
70struct InterfaceEntry
71{
72 sal_Int32 refCount;
73 void * pInterface;
74 uno_freeProxyFunc fpFreeProxy;
75 typelib_InterfaceTypeDescription * pTypeDescr;
76};
77
78struct ObjectEntry
79{
80 OUString oid;
81 sal_Int32 nRef;
82 ::std::vector< InterfaceEntry > aInterfaces;
83 bool mixedObject;
84
85 inline ObjectEntry( const OUString & rOId_ );
86
87 inline void append(
88 uno_DefaultEnvironment * pEnv,
89 void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
90 uno_freeProxyFunc fpFreeProxy );
91 inline InterfaceEntry * find(
92 typelib_InterfaceTypeDescription * pTypeDescr );
93 inline sal_Int32 find( void * iface_ptr, ::std::size_t pos );
94};
95
96//------------------------------------------------------------------------------
97struct FctPtrHash :
98 public ::std::unary_function< const void *, ::std::size_t >
99{
100 ::std::size_t operator () ( const void * pKey ) const
101 { return (::std::size_t) pKey; }
102};
103
104//------------------------------------------------------------------------------
105struct FctOUStringHash :
106 public ::std::unary_function< const OUString &, ::std::size_t >
107{
108 ::std::size_t operator () ( const OUString & rKey ) const
109 { return rKey.hashCode(); }
110};
111
112// mapping from environment name to environment
113typedef ::boost::unordered_map<
114 OUString, uno_Environment *, FctOUStringHash,
115 ::std::equal_to< OUString > > OUString2EnvironmentMap;
116
117// mapping from ptr to object entry
118typedef ::boost::unordered_map<
119 void *, ObjectEntry *, FctPtrHash,
120 ::std::equal_to< void * > > Ptr2ObjectMap;
121// mapping from oid to object entry
122typedef ::boost::unordered_map<
123 OUString, ObjectEntry *, FctOUStringHash,
124 ::std::equal_to< OUString > > OId2ObjectMap;
125
126
127//==============================================================================
128struct EnvironmentsData
129{
130 ::osl::Mutex mutex;
131 OUString2EnvironmentMap aName2EnvMap;
132
133 EnvironmentsData() : isDisposing(false) {}
134 ~EnvironmentsData();
135
136 inline void getEnvironment(
137 uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext );
138 inline void registerEnvironment( uno_Environment ** ppEnv );
139 inline void getRegisteredEnvironments(
140 uno_Environment *** pppEnvs, sal_Int32 * pnLen,
141 uno_memAlloc memAlloc, const OUString & rEnvDcp );
142
143 bool isDisposing;
144};
145
146namespace
147{
148 struct theEnvironmentsData : public rtl::Static< EnvironmentsData, theEnvironmentsData > {};
149}
150
151//==============================================================================
152struct uno_DefaultEnvironment : public uno_ExtEnvironment
153{
154 sal_Int32 nRef;
155 sal_Int32 nWeakRef;
156
157 ::osl::Mutex mutex;
158 Ptr2ObjectMap aPtr2ObjectMap;
159 OId2ObjectMap aOId2ObjectMap;
160
161 uno_DefaultEnvironment(
162 const OUString & rEnvDcp_, void * pContext_ );
163 ~uno_DefaultEnvironment();
164};
165
166//______________________________________________________________________________
167inline ObjectEntry::ObjectEntry( OUString const & rOId_ )
168 : oid( rOId_ ),
169 nRef( 0 ),
170 mixedObject( false )
171{
172 aInterfaces.reserve( 2 );
173}
174
175//______________________________________________________________________________
176inline void ObjectEntry::append(
177 uno_DefaultEnvironment * pEnv,
178 void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
179 uno_freeProxyFunc fpFreeProxy )
180{
181 InterfaceEntry aNewEntry;
182 if (! fpFreeProxy)
183 (*pEnv->acquireInterface)( pEnv, pInterface );
184 aNewEntry.refCount = 1;
185 aNewEntry.pInterface = pInterface;
186 aNewEntry.fpFreeProxy = fpFreeProxy;
187 typelib_typedescription_acquire( (typelib_TypeDescription *) pTypeDescr );
188 aNewEntry.pTypeDescr = pTypeDescr;
189
190 ::std::pair< Ptr2ObjectMap::iterator, bool > i(
191 pEnv->aPtr2ObjectMap.insert( Ptr2ObjectMap::value_type(
192 pInterface, this ) ) );
193 SAL_WARN_IF(do { if (true && (!i.second && (find(pInterface
, 0) == -1 || i.first->second != this))) { if (sizeof ::sal
::detail::getResult( ::sal::detail::StreamStart() << "map already contains "
<< i.first->second << " != " << this <<
" for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "map already contains " << i.first
->second << " != " << this << " for " <<
pInterface)); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "map already contains " <<
i.first->second << " != " << this << " for "
<< pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), sal_detail_stream); } } } while (false)
194 !i.second && (find(pInterface, 0) == -1 || i.first->second != this),do { if (true && (!i.second && (find(pInterface
, 0) == -1 || i.first->second != this))) { if (sizeof ::sal
::detail::getResult( ::sal::detail::StreamStart() << "map already contains "
<< i.first->second << " != " << this <<
" for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "map already contains " << i.first
->second << " != " << this << " for " <<
pInterface)); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "map already contains " <<
i.first->second << " != " << this << " for "
<< pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), sal_detail_stream); } } } while (false)
195 "cppu",do { if (true && (!i.second && (find(pInterface
, 0) == -1 || i.first->second != this))) { if (sizeof ::sal
::detail::getResult( ::sal::detail::StreamStart() << "map already contains "
<< i.first->second << " != " << this <<
" for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "map already contains " << i.first
->second << " != " << this << " for " <<
pInterface)); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "map already contains " <<
i.first->second << " != " << this << " for "
<< pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), sal_detail_stream); } } } while (false)
196 "map already contains " << i.first->second << " != " << this << " for "do { if (true && (!i.second && (find(pInterface
, 0) == -1 || i.first->second != this))) { if (sizeof ::sal
::detail::getResult( ::sal::detail::StreamStart() << "map already contains "
<< i.first->second << " != " << this <<
" for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "map already contains " << i.first
->second << " != " << this << " for " <<
pInterface)); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "map already contains " <<
i.first->second << " != " << this << " for "
<< pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), sal_detail_stream); } } } while (false)
197 << pInterface)do { if (true && (!i.second && (find(pInterface
, 0) == -1 || i.first->second != this))) { if (sizeof ::sal
::detail::getResult( ::sal::detail::StreamStart() << "map already contains "
<< i.first->second << " != " << this <<
" for " << pInterface) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "map already contains " << i.first
->second << " != " << this << " for " <<
pInterface)); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "map already contains " <<
i.first->second << " != " << this << " for "
<< pInterface; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("cppu"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "197" ": "), sal_detail_stream); } } } while (false)
;
198 aInterfaces.push_back( aNewEntry );
199}
200
201//______________________________________________________________________________
202inline InterfaceEntry * ObjectEntry::find(
203 typelib_InterfaceTypeDescription * pTypeDescr_ )
204{
205 OSL_ASSERT( ! aInterfaces.empty() )do { if (true && (!(! aInterfaces.empty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "205" ": "), "OSL_ASSERT: %s", "! aInterfaces.empty()");
} } while (false)
;
206 if (aInterfaces.empty())
207 return 0;
208
209 // shortcut common case:
210 OUString const & type_name =
211 OUString::unacquired(
212 &((typelib_TypeDescription *) pTypeDescr_)->pTypeName );
213 if ( type_name == "com.sun.star.uno.XInterface" )
214 {
215 return &aInterfaces[ 0 ];
216 }
217
218 ::std::size_t nSize = aInterfaces.size();
219 for ( ::std::size_t nPos = 0; nPos < nSize; ++nPos )
220 {
221 typelib_InterfaceTypeDescription * pITD =
222 aInterfaces[ nPos ].pTypeDescr;
223 while (pITD)
224 {
225 if (td_equals( pITD, pTypeDescr_ ))
226 return &aInterfaces[ nPos ];
227 pITD = pITD->pBaseTypeDescription;
228 }
229 }
230 return 0;
231}
232
233//______________________________________________________________________________
234inline sal_Int32 ObjectEntry::find(
235 void * iface_ptr, ::std::size_t pos )
236{
237 ::std::size_t size = aInterfaces.size();
238 for ( ; pos < size; ++pos )
239 {
240 if (aInterfaces[ pos ].pInterface == iface_ptr)
241 return pos;
242 }
243 return -1;
244}
245
246extern "C"
247{
248
249//------------------------------------------------------------------------------
250static void SAL_CALL defenv_registerInterface(
251 uno_ExtEnvironment * pEnv, void ** ppInterface,
252 rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
253{
254 OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" )do { if (true && (!(pEnv && ppInterface &&
pOId && pTypeDescr))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "254" ": "), "%s", "### null ptr!"); } } while (false)
;
255 OUString const & rOId = OUString::unacquired( &pOId );
256
257 uno_DefaultEnvironment * that =
258 static_cast< uno_DefaultEnvironment * >( pEnv );
259 ::osl::ClearableMutexGuard guard( that->mutex );
260
261 // try to insert dummy 0:
262 std::pair<OId2ObjectMap::iterator, bool> const insertion(
263 that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, (ObjectEntry*)0 ) ) );
264 if (insertion.second)
265 {
266 ObjectEntry * pOEntry = new ObjectEntry( rOId );
267 insertion.first->second = pOEntry;
268 ++pOEntry->nRef; // another register call on object
269 pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
270 }
271 else // object entry exists
272 {
273 ObjectEntry * pOEntry = insertion.first->second;
274 ++pOEntry->nRef; // another register call on object
275 InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
276
277 if (pIEntry) // type entry exists
278 {
279 ++pIEntry->refCount;
280 if (pIEntry->pInterface != *ppInterface)
281 {
282 void * pInterface = pIEntry->pInterface;
283 (*pEnv->acquireInterface)( pEnv, pInterface );
284 guard.clear();
285 (*pEnv->releaseInterface)( pEnv, *ppInterface );
286 *ppInterface = pInterface;
287 }
288 }
289 else
290 {
291 pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
292 }
293 }
294}
295
296//------------------------------------------------------------------------------
297static void SAL_CALL defenv_registerProxyInterface(
298 uno_ExtEnvironment * pEnv, void ** ppInterface, uno_freeProxyFunc freeProxy,
299 rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
300{
301 OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr && freeProxy,do { if (true && (!(pEnv && ppInterface &&
pOId && pTypeDescr && freeProxy))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "302" ": "), "%s", "### null ptr!"); } } while (false)
302 "### null ptr!" )do { if (true && (!(pEnv && ppInterface &&
pOId && pTypeDescr && freeProxy))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "302" ": "), "%s", "### null ptr!"); } } while (false)
;
303 OUString const & rOId = OUString::unacquired( &pOId );
304
305 uno_DefaultEnvironment * that =
306 static_cast< uno_DefaultEnvironment * >( pEnv );
307 ::osl::ClearableMutexGuard guard( that->mutex );
308
309 // try to insert dummy 0:
310 std::pair<OId2ObjectMap::iterator, bool> const insertion(
311 that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, (ObjectEntry*)0 ) ) );
312 if (insertion.second)
1
Taking true branch
313 {
314 ObjectEntry * pOEntry = new ObjectEntry( rOId );
315 insertion.first->second = pOEntry;
316 ++pOEntry->nRef; // another register call on object
317 pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
2
Dereference of null pointer (loaded from variable 'ppInterface')
318 }
319 else // object entry exists
320 {
321 ObjectEntry * pOEntry = insertion.first->second;
322
323 // first registration was an original, then registerProxyInterface():
324 pOEntry->mixedObject |=
325 (!pOEntry->aInterfaces.empty() &&
326 pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0);
327
328 ++pOEntry->nRef; // another register call on object
329 InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
330
331 if (pIEntry) // type entry exists
332 {
333 if (pIEntry->pInterface == *ppInterface)
334 {
335 ++pIEntry->refCount;
336 }
337 else
338 {
339 void * pInterface = pIEntry->pInterface;
340 (*pEnv->acquireInterface)( pEnv, pInterface );
341 --pOEntry->nRef; // manual revoke of proxy to be freed
342 guard.clear();
343 (*freeProxy)( pEnv, *ppInterface );
344 *ppInterface = pInterface;
345 }
346 }
347 else
348 {
349 pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
350 }
351 }
352}
353
354//------------------------------------------------------------------------------
355static void SAL_CALL s_stub_defenv_revokeInterface(va_list * pParam)
356{
357 uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *)__builtin_va_arg(*pParam, uno_ExtEnvironment *);
358 void * pInterface = va_arg(*pParam, void *)__builtin_va_arg(*pParam, void *);
359
360 OSL_ENSURE( pEnv && pInterface, "### null ptr!" )do { if (true && (!(pEnv && pInterface))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "360" ": "), "%s", "### null ptr!"); } } while (false)
;
361 uno_DefaultEnvironment * that =
362 static_cast< uno_DefaultEnvironment * >( pEnv );
363 ::osl::ClearableMutexGuard guard( that->mutex );
364
365 Ptr2ObjectMap::const_iterator const iFind(
366 that->aPtr2ObjectMap.find( pInterface ) );
367 OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() )do { if (true && (!(iFind != that->aPtr2ObjectMap.
end()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), (
"legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "367" ": "), "OSL_ASSERT: %s", "iFind != that->aPtr2ObjectMap.end()"
); } } while (false)
;
368 ObjectEntry * pOEntry = iFind->second;
369 if (! --pOEntry->nRef)
370 {
371 // cleanup maps
372 that->aOId2ObjectMap.erase( pOEntry->oid );
373 sal_Int32 nPos;
374 for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
375 {
376 that->aPtr2ObjectMap.erase( pOEntry->aInterfaces[nPos].pInterface );
377 }
378
379 // the last proxy interface of the environment might kill this
380 // environment, because of releasing its language binding!!!
381 guard.clear();
382
383 // release interfaces
384 for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
385 {
386 InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos];
387 typelib_typedescription_release(
388 (typelib_TypeDescription *) rEntry.pTypeDescr );
389 if (rEntry.fpFreeProxy) // is proxy or used interface?
390 {
391 (*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface );
392 }
393 else
394 {
395 (*pEnv->releaseInterface)( pEnv, rEntry.pInterface );
396 }
397 }
398
399 delete pOEntry;
400 }
401 else if (pOEntry->mixedObject)
402 {
403 OSL_ASSERT( !pOEntry->aInterfaces.empty() &&do { if (true && (!(!pOEntry->aInterfaces.empty() &&
pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "404" ": "), "OSL_ASSERT: %s", "!pOEntry->aInterfaces.empty() && pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0"
); } } while (false)
404 pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0 )do { if (true && (!(!pOEntry->aInterfaces.empty() &&
pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "404" ": "), "OSL_ASSERT: %s", "!pOEntry->aInterfaces.empty() && pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0"
); } } while (false)
;
405
406 sal_Int32 index = pOEntry->find( pInterface, 1 );
407 OSL_ASSERT( index > 0 )do { if (true && (!(index > 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "407" ": "), "OSL_ASSERT: %s", "index > 0"); } } while
(false)
;
408 if (index > 0)
409 {
410 InterfaceEntry & entry = pOEntry->aInterfaces[ index ];
411 OSL_ASSERT( entry.pInterface == pInterface )do { if (true && (!(entry.pInterface == pInterface)))
{ sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx" ":"
"411" ": "), "OSL_ASSERT: %s", "entry.pInterface == pInterface"
); } } while (false)
;
412 if (entry.fpFreeProxy != 0)
413 {
414 --entry.refCount;
415 if (entry.refCount == 0)
416 {
417 uno_freeProxyFunc fpFreeProxy = entry.fpFreeProxy;
418 typelib_TypeDescription * pTypeDescr =
419 reinterpret_cast< typelib_TypeDescription * >(
420 entry.pTypeDescr );
421
422 pOEntry->aInterfaces.erase(
423 pOEntry->aInterfaces.begin() + index );
424 if (pOEntry->find( pInterface, index ) < 0)
425 {
426 // proxy ptr not registered for another interface:
427 // remove from ptr map
428#if OSL_DEBUG_LEVEL1 > 0
429 ::std::size_t erased =
430#endif
431 that->aPtr2ObjectMap.erase( pInterface );
432 OSL_ASSERT( erased == 1 )do { if (true && (!(erased == 1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "432" ": "), "OSL_ASSERT: %s", "erased == 1"); } } while
(false)
;
433 }
434
435 guard.clear();
436
437 typelib_typedescription_release( pTypeDescr );
438 (*fpFreeProxy)( pEnv, pInterface );
439 }
440 }
441 }
442 }
443}
444
445static void SAL_CALL defenv_revokeInterface(uno_ExtEnvironment * pEnv, void * pInterface)
446{
447 uno_Environment_invoke(&pEnv->aBase, s_stub_defenv_revokeInterface, pEnv, pInterface);
448}
449
450//------------------------------------------------------------------------------
451static void SAL_CALL defenv_getObjectIdentifier(
452 uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
453{
454 OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" )do { if (true && (!(pEnv && ppOId && pInterface
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx" ":"
"454" ": "), "%s", "### null ptr!"); } } while (false)
;
455 if (*ppOId)
456 {
457 ::rtl_uString_release( *ppOId );
458 *ppOId = 0;
459 }
460
461 uno_DefaultEnvironment * that =
462 static_cast< uno_DefaultEnvironment * >( pEnv );
463 ::osl::ClearableMutexGuard guard( that->mutex );
464
465 Ptr2ObjectMap::const_iterator const iFind(
466 that->aPtr2ObjectMap.find( pInterface ) );
467 if (iFind == that->aPtr2ObjectMap.end())
468 {
469 guard.clear();
470 (*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface );
471 }
472 else
473 {
474 rtl_uString * hstr = iFind->second->oid.pData;
475 rtl_uString_acquire( hstr );
476 *ppOId = hstr;
477 }
478}
479
480//------------------------------------------------------------------------------
481static void SAL_CALL defenv_getRegisteredInterface(
482 uno_ExtEnvironment * pEnv, void ** ppInterface,
483 rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
484{
485 OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" )do { if (true && (!(pEnv && ppInterface &&
pOId && pTypeDescr))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "485" ": "), "%s", "### null ptr!"); } } while (false)
;
486 if (*ppInterface)
487 {
488 (*pEnv->releaseInterface)( pEnv, *ppInterface );
489 *ppInterface = 0;
490 }
491
492 OUString const & rOId = OUString::unacquired( &pOId );
493 uno_DefaultEnvironment * that =
494 static_cast< uno_DefaultEnvironment * >( pEnv );
495 ::osl::MutexGuard guard( that->mutex );
496
497 OId2ObjectMap::const_iterator const iFind
498 ( that->aOId2ObjectMap.find( rOId ) );
499 if (iFind != that->aOId2ObjectMap.end())
500 {
501 InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr );
502 if (pIEntry)
503 {
504 (*pEnv->acquireInterface)( pEnv, pIEntry->pInterface );
505 *ppInterface = pIEntry->pInterface;
506 }
507 }
508}
509
510//------------------------------------------------------------------------------
511static void SAL_CALL defenv_getRegisteredInterfaces(
512 uno_ExtEnvironment * pEnv, void *** pppInterfaces, sal_Int32 * pnLen,
513 uno_memAlloc memAlloc )
514{
515 OSL_ENSURE( pEnv && pppInterfaces && pnLen && memAlloc, "### null ptr!" )do { if (true && (!(pEnv && pppInterfaces &&
pnLen && memAlloc))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "515" ": "), "%s", "### null ptr!"); } } while (false)
;
516 uno_DefaultEnvironment * that =
517 static_cast< uno_DefaultEnvironment * >( pEnv );
518 ::osl::MutexGuard guard( that->mutex );
519
520 sal_Int32 nLen = that->aPtr2ObjectMap.size();
521 sal_Int32 nPos = 0;
522 void ** ppInterfaces = (void **) (*memAlloc)( nLen * sizeof (void *) );
523
524 Ptr2ObjectMap::const_iterator iPos( that->aPtr2ObjectMap.begin() );
525 Ptr2ObjectMap::const_iterator const iEnd( that->aPtr2ObjectMap.end() );
526 while (iPos != iEnd)
527 {
528 (*pEnv->acquireInterface)( pEnv, ppInterfaces[nPos++] = (*iPos).first );
529 ++iPos;
530 }
531
532 *pppInterfaces = ppInterfaces;
533 *pnLen = nLen;
534}
535
536//------------------------------------------------------------------------------
537static void SAL_CALL defenv_acquire( uno_Environment * pEnv )
538{
539 uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
540 ::osl_incrementInterlockedCount( &that->nWeakRef );
541 ::osl_incrementInterlockedCount( &that->nRef );
542}
543
544//------------------------------------------------------------------------------
545static void SAL_CALL defenv_release( uno_Environment * pEnv )
546{
547 uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
548 if (! ::osl_decrementInterlockedCount( &that->nRef ))
549 {
550 // invoke dispose callback
551 if (pEnv->environmentDisposing)
552 {
553 (*pEnv->environmentDisposing)( pEnv );
554 }
555
556 OSL_ENSURE( that->aOId2ObjectMap.empty(), "### object entries left!" )do { if (true && (!(that->aOId2ObjectMap.empty()))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx" ":"
"556" ": "), "%s", "### object entries left!"); } } while (false
)
;
557 }
558 // free memory if no weak refs left
559 if (! ::osl_decrementInterlockedCount( &that->nWeakRef ))
560 {
561 delete that;
562 }
563}
564
565//------------------------------------------------------------------------------
566static void SAL_CALL defenv_acquireWeak( uno_Environment * pEnv )
567{
568 uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
569 ::osl_incrementInterlockedCount( &that->nWeakRef );
570}
571
572//------------------------------------------------------------------------------
573static void SAL_CALL defenv_releaseWeak( uno_Environment * pEnv )
574{
575 uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
576 if (! ::osl_decrementInterlockedCount( &that->nWeakRef ))
577 {
578 delete that;
579 }
580}
581
582//------------------------------------------------------------------------------
583static void SAL_CALL defenv_harden(
584 uno_Environment ** ppHardEnv, uno_Environment * pEnv )
585{
586 if (*ppHardEnv)
587 {
588 (*(*ppHardEnv)->release)( *ppHardEnv );
589 *ppHardEnv = 0;
590 }
591
592 EnvironmentsData & rData = theEnvironmentsData::get();
593
594 if (rData.isDisposing)
595 return;
596
597 uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
598 {
599 ::osl::MutexGuard guard( rData.mutex );
600 if (1 == ::osl_incrementInterlockedCount( &that->nRef )) // is dead
601 {
602 that->nRef = 0;
603 return;
604 }
605 }
606 ::osl_incrementInterlockedCount( &that->nWeakRef );
607 *ppHardEnv = pEnv;
608}
609
610//------------------------------------------------------------------------------
611static void SAL_CALL defenv_dispose( SAL_UNUSED_PARAMETER__attribute__ ((unused)) uno_Environment * )
612{
613}
614}
615
616//______________________________________________________________________________
617uno_DefaultEnvironment::uno_DefaultEnvironment(
618 const OUString & rEnvDcp_, void * pContext_ )
619 : nRef( 0 ),
620 nWeakRef( 0 )
621{
622 uno_Environment * that = reinterpret_cast< uno_Environment * >(this);
623 that->pReserved = 0;
624 // functions
625 that->acquire = defenv_acquire;
626 that->release = defenv_release;
627 that->acquireWeak = defenv_acquireWeak;
628 that->releaseWeak = defenv_releaseWeak;
629 that->harden = defenv_harden;
630 that->dispose = defenv_dispose;
631 that->pExtEnv = this;
632 // identifier
633 ::rtl_uString_acquire( rEnvDcp_.pData );
634 that->pTypeName = rEnvDcp_.pData;
635 that->pContext = pContext_;
636
637 // will be late initialized
638 that->environmentDisposing = 0;
639
640 uno_ExtEnvironment::registerInterface = defenv_registerInterface;
641 uno_ExtEnvironment::registerProxyInterface = defenv_registerProxyInterface;
642 uno_ExtEnvironment::revokeInterface = defenv_revokeInterface;
643 uno_ExtEnvironment::getObjectIdentifier = defenv_getObjectIdentifier;
644 uno_ExtEnvironment::getRegisteredInterface = defenv_getRegisteredInterface;
645 uno_ExtEnvironment::getRegisteredInterfaces =
646 defenv_getRegisteredInterfaces;
647
648}
649
650//______________________________________________________________________________
651uno_DefaultEnvironment::~uno_DefaultEnvironment()
652{
653 ::rtl_uString_release( ((uno_Environment *) this)->pTypeName );
654}
655
656//==============================================================================
657static void writeLine(
658 void * stream, const sal_Char * pLine, const sal_Char * pFilter )
659{
660 if (pFilter && *pFilter)
661 {
662 // lookup pFilter in pLine
663 while (*pLine)
664 {
665 if (*pLine == *pFilter)
666 {
667 sal_Int32 nPos = 1;
668 while (pLine[nPos] && pFilter[nPos] == pLine[nPos])
669 {
670 ++nPos;
671 }
672 if (! pFilter[nPos])
673 {
674 if (stream)
675 {
676 fprintf( (FILE *) stream, "%s\n", pLine );
677 }
678 else
679 {
680 OSL_TRACE( "%s", pLine )do { if (true && (1 > 0)) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "680" ": "), "%s", pLine); } } while (false)
;
681 }
682 }
683 }
684 ++pLine;
685 }
686 }
687 else
688 {
689 if (stream)
690 {
691 fprintf( (FILE *) stream, "%s\n", pLine );
692 }
693 else
694 {
695 fprintf( stderrstderr, "%s\n", pLine );
696 }
697 }
698}
699
700//==============================================================================
701static void writeLine(
702 void * stream, const OUString & rLine, const sal_Char * pFilter )
703{
704 ::rtl::OString aLine( ::rtl::OUStringToOString(
705 rLine, RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11)) ) );
706 writeLine( stream, aLine.getStr(), pFilter );
707}
708
709//##############################################################################
710extern "C" CPPU_DLLPUBLIC__attribute__ ((visibility("default"))) void SAL_CALL uno_dumpEnvironment(
711 void * stream, uno_Environment * pEnv, const sal_Char * pFilter )
712 SAL_THROW_EXTERN_C()throw ()
713{
714 OSL_ENSURE( pEnv, "### null ptr!" )do { if (true && (!(pEnv))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "714" ": "), "%s", "### null ptr!"); } } while (false)
;
715 ::rtl::OUStringBuffer buf;
716
717 if (! pEnv->pExtEnv)
718 {
719 writeLine( stream, "###################################"
720 "###########################################", pFilter );
721 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment: ")(&("environment: ")[0]), ((sal_Int32)(sizeof ("environment: "
) / sizeof (("environment: ")[0]))-1)
);
722 buf.append( pEnv->pTypeName );
723 writeLine( stream, buf.makeStringAndClear(), pFilter );
724 writeLine( stream, "NO INTERFACE INFORMATION AVAILABLE!", pFilter );
725 return;
726 }
727
728 writeLine( stream, "########################################"
729 "######################################", pFilter );
730 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment dump: ")(&("environment dump: ")[0]), ((sal_Int32)(sizeof ("environment dump: "
) / sizeof (("environment dump: ")[0]))-1)
);
731 buf.append( pEnv->pTypeName );
732 writeLine( stream, buf.makeStringAndClear(), pFilter );
733
734 uno_DefaultEnvironment * that =
735 reinterpret_cast< uno_DefaultEnvironment * >(pEnv);
736 ::osl::MutexGuard guard( that->mutex );
737
738 Ptr2ObjectMap ptr2obj( that->aPtr2ObjectMap );
739 OId2ObjectMap::const_iterator iPos( that->aOId2ObjectMap.begin() );
740 while (iPos != that->aOId2ObjectMap.end())
741 {
742 ObjectEntry * pOEntry = iPos->second;
743
744 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("+ ")(&("+ ")[0]), ((sal_Int32)(sizeof ("+ ") / sizeof (("+ ")
[0]))-1)
);
745 if (pOEntry->mixedObject)
746 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("mixed ")(&("mixed ")[0]), ((sal_Int32)(sizeof ("mixed ") / sizeof
(("mixed ")[0]))-1)
);
747 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("object entry: nRef=")(&("object entry: nRef=")[0]), ((sal_Int32)(sizeof ("object entry: nRef="
) / sizeof (("object entry: nRef=")[0]))-1)
);
748 buf.append( pOEntry->nRef, 10 );
749 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; oid=\"")(&("; oid=\"")[0]), ((sal_Int32)(sizeof ("; oid=\"") / sizeof
(("; oid=\"")[0]))-1)
);
750 buf.append( pOEntry->oid );
751 buf.append( (sal_Unicode) '\"' );
752 writeLine( stream, buf.makeStringAndClear(), pFilter );
753
754 for ( ::std::size_t nPos = 0;
755 nPos < pOEntry->aInterfaces.size(); ++nPos )
756 {
757 const InterfaceEntry & rIEntry = pOEntry->aInterfaces[nPos];
758
759 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" - ")(&(" - ")[0]), ((sal_Int32)(sizeof (" - ") / sizeof ((" - "
)[0]))-1)
);
760 buf.append(
761 ((typelib_TypeDescription *) rIEntry.pTypeDescr)->pTypeName );
762 if (rIEntry.fpFreeProxy)
763 {
764 buf.appendAscii(
765 RTL_CONSTASCII_STRINGPARAM("; proxy free=0x")(&("; proxy free=0x")[0]), ((sal_Int32)(sizeof ("; proxy free=0x"
) / sizeof (("; proxy free=0x")[0]))-1)
);
766 buf.append(
767 reinterpret_cast< sal_IntPtr >(rIEntry.fpFreeProxy), 16 );
768 }
769 else
770 {
771 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; original")(&("; original")[0]), ((sal_Int32)(sizeof ("; original") /
sizeof (("; original")[0]))-1)
);
772 }
773 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; ptr=0x")(&("; ptr=0x")[0]), ((sal_Int32)(sizeof ("; ptr=0x") / sizeof
(("; ptr=0x")[0]))-1)
);
774 buf.append(
775 reinterpret_cast< sal_IntPtr >(rIEntry.pInterface), 16 );
776
777 if (pOEntry->find( rIEntry.pInterface, nPos + 1 ) < 0)
778 {
779 ::std::size_t erased = ptr2obj.erase( rIEntry.pInterface );
780 if (erased != 1)
781 {
782 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM((&(" (ptr not found in map!)")[0]), ((sal_Int32)(sizeof (
" (ptr not found in map!)") / sizeof ((" (ptr not found in map!)"
)[0]))-1)
783 " (ptr not found in map!)")(&(" (ptr not found in map!)")[0]), ((sal_Int32)(sizeof (
" (ptr not found in map!)") / sizeof ((" (ptr not found in map!)"
)[0]))-1)
);
784 }
785 }
786 writeLine( stream, buf.makeStringAndClear(), pFilter );
787 }
788 ++iPos;
789 }
790 if (! ptr2obj.empty())
791 writeLine( stream, "ptr map inconsistency!!!", pFilter );
792 writeLine( stream, "#####################################"
793 "#########################################", pFilter );
794}
795
796//##############################################################################
797extern "C" CPPU_DLLPUBLIC__attribute__ ((visibility("default"))) void SAL_CALL uno_dumpEnvironmentByName(
798 void * stream, rtl_uString * pEnvDcp, const sal_Char * pFilter )
799 SAL_THROW_EXTERN_C()throw ()
800{
801 uno_Environment * pEnv = 0;
802 uno_getEnvironment( &pEnv, pEnvDcp, 0 );
803 if (pEnv)
804 {
805 ::uno_dumpEnvironment( stream, pEnv, pFilter );
806 (*pEnv->release)( pEnv );
807 }
808 else
809 {
810 ::rtl::OUStringBuffer buf( 32 );
811 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment \"")(&("environment \"")[0]), ((sal_Int32)(sizeof ("environment \""
) / sizeof (("environment \"")[0]))-1)
);
812 buf.append( pEnvDcp );
813 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not exist!")(&("\" does not exist!")[0]), ((sal_Int32)(sizeof ("\" does not exist!"
) / sizeof (("\" does not exist!")[0]))-1)
);
814 writeLine( stream, buf.makeStringAndClear(), pFilter );
815 }
816}
817
818namespace
819{
820 class makeOIdPart
821 {
822 private:
823 OUString m_sOidPart;
824 public:
825 makeOIdPart()
826 {
827 ::rtl::OUStringBuffer aRet( 64 );
828 aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];")(&("];")[0]), ((sal_Int32)(sizeof ("];") / sizeof (("];")
[0]))-1)
);
829 // pid
830 oslProcessInfo info;
831 info.Size = sizeof(oslProcessInfo);
832 if (::osl_getProcessInfo( 0, osl_Process_IDENTIFIER0x0001, &info ) ==
833 osl_Process_E_None)
834 {
835 aRet.append( (sal_Int64)info.Ident, 16 );
836 }
837 else
838 {
839 aRet.appendAscii(
840 RTL_CONSTASCII_STRINGPARAM("unknown process id")(&("unknown process id")[0]), ((sal_Int32)(sizeof ("unknown process id"
) / sizeof (("unknown process id")[0]))-1)
);
841 }
842 // good guid
843 sal_uInt8 ar[16];
844 ::rtl_getGlobalProcessId( ar );
845 aRet.append( (sal_Unicode)';' );
846 for ( sal_Int32 i = 0; i < 16; ++i )
847 aRet.append( (sal_Int32)ar[i], 16 );
848
849 m_sOidPart = aRet.makeStringAndClear();
850 }
851 const OUString& getOIdPart() const { return m_sOidPart; }
852 };
853
854 class theStaticOIdPart : public rtl::Static<makeOIdPart, theStaticOIdPart> {};
855}
856
857//------------------------------------------------------------------------------
858inline static const OUString & unoenv_getStaticOIdPart()
859{
860 return theStaticOIdPart::get().getOIdPart();
861}
862
863extern "C"
864{
865
866//------------------------------------------------------------------------------
867static void SAL_CALL unoenv_computeObjectIdentifier(
868 uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
869{
870 OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" )do { if (true && (!(pEnv && ppOId && pInterface
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx" ":"
"870" ": "), "%s", "### null ptr!"); } } while (false)
;
871 if (*ppOId)
872 {
873 ::rtl_uString_release( *ppOId );
874 *ppOId = 0;
875 }
876
877 uno_Interface * pUnoI = (uno_Interface *)
878 ::cppu::binuno_queryInterface(
879 pInterface, *typelib_static_type_getByTypeClass(
880 typelib_TypeClass_INTERFACE ) );
881 if (0 != pUnoI)
882 {
883 (*pUnoI->release)( pUnoI );
884 // interface
885 ::rtl::OUStringBuffer oid( 64 );
886 oid.append( reinterpret_cast< sal_Int64 >(pUnoI), 16 );
887 oid.append( static_cast< sal_Unicode >(';') );
888 // environment[context]
889 oid.append( ((uno_Environment *) pEnv)->pTypeName );
890 oid.append( static_cast< sal_Unicode >('[') );
891 oid.append( reinterpret_cast< sal_Int64 >(
892 reinterpret_cast<
893 uno_Environment * >(pEnv)->pContext ), 16 );
894 // process;good guid
895 oid.append( unoenv_getStaticOIdPart() );
896 OUString aStr( oid.makeStringAndClear() );
897 ::rtl_uString_acquire( *ppOId = aStr.pData );
898 }
899}
900
901//==============================================================================
902static void SAL_CALL unoenv_acquireInterface(
903 SAL_UNUSED_PARAMETER__attribute__ ((unused)) uno_ExtEnvironment *, void * pUnoI_ )
904{
905 uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
906 (*pUnoI->acquire)( pUnoI );
907}
908
909//==============================================================================
910static void SAL_CALL unoenv_releaseInterface(
911 SAL_UNUSED_PARAMETER__attribute__ ((unused)) uno_ExtEnvironment *, void * pUnoI_ )
912{
913 uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
914 (*pUnoI->release)( pUnoI );
915}
916}
917
918//______________________________________________________________________________
919EnvironmentsData::~EnvironmentsData()
920{
921 ::osl::MutexGuard guard( mutex );
922 isDisposing = true;
923
924 for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
925 iPos != aName2EnvMap.end(); ++iPos )
926 {
927 uno_Environment * pWeak = iPos->second;
928 uno_Environment * pHard = 0;
929 (*pWeak->harden)( &pHard, pWeak );
930 (*pWeak->releaseWeak)( pWeak );
931
932 if (pHard)
933 {
934#if OSL_DEBUG_LEVEL1 > 1
935 ::uno_dumpEnvironment( 0, pHard, 0 );
936#endif
937 (*pHard->dispose)( pHard ); // send explicit dispose
938 (*pHard->release)( pHard );
939 }
940 }
941}
942
943//______________________________________________________________________________
944inline void EnvironmentsData::getEnvironment(
945 uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext )
946{
947 if (*ppEnv)
948 {
949 (*(*ppEnv)->release)( *ppEnv );
950 *ppEnv = 0;
951 }
952
953 OUString aKey(
954 OUString::valueOf( reinterpret_cast< sal_IntPtr >(pContext) ) );
955 aKey += rEnvDcp;
956
957 // try to find registered mapping
958 OUString2EnvironmentMap::const_iterator const iFind(
959 aName2EnvMap.find( aKey ) );
960 if (iFind != aName2EnvMap.end())
961 {
962 uno_Environment * pWeak = iFind->second;
963 (*pWeak->harden)( ppEnv, pWeak );
964 }
965}
966
967//______________________________________________________________________________
968inline void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv )
969{
970 OSL_ENSURE( ppEnv, "### null ptr!" )do { if (true && (!(ppEnv))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "970" ": "), "%s", "### null ptr!"); } } while (false)
;
971 uno_Environment * pEnv = *ppEnv;
972
973 OUString aKey(
974 OUString::valueOf( reinterpret_cast< sal_IntPtr >(pEnv->pContext) ) );
975 aKey += pEnv->pTypeName;
976
977 // try to find registered environment
978 OUString2EnvironmentMap::const_iterator const iFind(
979 aName2EnvMap.find( aKey ) );
980 if (iFind == aName2EnvMap.end())
981 {
982 (*pEnv->acquireWeak)( pEnv );
983 ::std::pair< OUString2EnvironmentMap::iterator, bool > insertion (
984 aName2EnvMap.insert(
985 OUString2EnvironmentMap::value_type( aKey, pEnv ) ) );
986 SAL_WARN_IF( !insertion.second, "cppu", "key " << aKey << " already in env map" )do { if (true && (!insertion.second)) { if (sizeof ::
sal::detail::getResult( ::sal::detail::StreamStart() <<
"key " << aKey << " already in env map") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu"), (
"/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx" ":" "986"
": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "key " << aKey << " already in env map"
)); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "key " << aKey << " already in env map"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("cppu")
, ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx" ":"
"986" ": "), sal_detail_stream); } } } while (false)
;
987 }
988 else
989 {
990 uno_Environment * pHard = 0;
991 uno_Environment * pWeak = iFind->second;
992 (*pWeak->harden)( &pHard, pWeak );
993 if (pHard)
994 {
995 if (pEnv)
996 (*pEnv->release)( pEnv );
997 *ppEnv = pHard;
998 }
999 else // registered one is dead
1000 {
1001 (*pWeak->releaseWeak)( pWeak );
1002 (*pEnv->acquireWeak)( pEnv );
1003 aName2EnvMap[ aKey ] = pEnv;
1004 }
1005 }
1006}
1007
1008//______________________________________________________________________________
1009inline void EnvironmentsData::getRegisteredEnvironments(
1010 uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
1011 const OUString & rEnvDcp )
1012{
1013 OSL_ENSURE( pppEnvs && pnLen && memAlloc, "### null ptr!" )do { if (true && (!(pppEnvs && pnLen &&
memAlloc))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "1013" ": "), "%s", "### null ptr!"); } } while (false)
;
1014
1015 // max size
1016 uno_Environment ** ppFound = (uno_Environment **)alloca(__builtin_alloca (sizeof(uno_Environment *) * aName2EnvMap.size
())
1017 sizeof(uno_Environment *) * aName2EnvMap.size() )__builtin_alloca (sizeof(uno_Environment *) * aName2EnvMap.size
())
;
1018 sal_Int32 nSize = 0;
1019
1020 // find matching environment
1021 for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
1022 iPos != aName2EnvMap.end(); ++iPos )
1023 {
1024 uno_Environment * pWeak = iPos->second;
1025 if (rEnvDcp.isEmpty() ||
1026 rEnvDcp.equals( pWeak->pTypeName ))
1027 {
1028 ppFound[nSize] = 0;
1029 (*pWeak->harden)( &ppFound[nSize], pWeak );
1030 if (ppFound[nSize])
1031 ++nSize;
1032 }
1033 }
1034
1035 *pnLen = nSize;
1036 if (nSize)
1037 {
1038 *pppEnvs = (uno_Environment **) (*memAlloc)(
1039 sizeof (uno_Environment *) * nSize );
1040 OSL_ASSERT( *pppEnvs )do { if (true && (!(*pppEnvs))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "1040" ": "), "OSL_ASSERT: %s", "*pppEnvs"); } } while (
false)
;
1041 while (nSize--)
1042 {
1043 (*pppEnvs)[nSize] = ppFound[nSize];
1044 }
1045 }
1046 else
1047 {
1048 *pppEnvs = 0;
1049 }
1050}
1051
1052static bool loadEnv(OUString const & cLibStem,
1053 uno_Environment * pEnv)
1054{
1055#ifdef DISABLE_DYNLOADING
1056 oslModule hMod;
1057 uno_initEnvironmentFunc fpInit = NULL__null;
1058
1059 if ( cLibStem == CPPU_CURRENT_LANGUAGE_BINDING_NAME"gcc3" "_uno" )
1060 fpInit = CPPU_ENV_uno_initEnvironment;
1061 else
1062 {
1063#if OSL_DEBUG_LEVEL1 > 1
1064 OSL_TRACE( "%s: Unhandled env: %s", __PRETTY_FUNCTION__, OUStringToOString( cLibStem, RTL_TEXTENCODING_ASCII_US).getStr() )do { if (true && (1 > 0)) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "1064" ": "), "%s: Unhandled env: %s", __PRETTY_FUNCTION__
, OUStringToOString( cLibStem, (((rtl_TextEncoding) 11))).getStr
()); } } while (false)
;
1065#endif
1066 return false;
1067 }
1068 // In the DISABLE_DYNLOADING case the functions that hMod is
1069 // passed to below don't do anything with it anyway.
1070 hMod = 0;
1071#else
1072 // late init with some code from matching uno language binding
1073 // will be unloaded by environment
1074 oslModule hMod = cppu::detail::loadModule( cLibStem );
1075
1076 if (!hMod)
1077 return false;
1078
1079 OUString aSymbolName(RTL_CONSTASCII_USTRINGPARAM(UNO_INIT_ENVIRONMENT)(&("uno_initEnvironment")[0]), ((sal_Int32)((sizeof ("uno_initEnvironment"
) / sizeof (("uno_initEnvironment")[0]))-1)), (((rtl_TextEncoding
) 11))
);
1080 uno_initEnvironmentFunc fpInit = (uno_initEnvironmentFunc)
1081 ::osl_getFunctionSymbol( hMod, aSymbolName.pData );
1082#endif
1083
1084 if (!fpInit)
1085 {
1086 ::osl_unloadModule( hMod );
1087 return false;
1088 }
1089
1090 (*fpInit)( pEnv ); // init of environment
1091 ::rtl_registerModuleForUnloading( hMod );
1092
1093 return true;
1094}
1095
1096
1097extern "C"
1098{
1099
1100//------------------------------------------------------------------------------
1101static uno_Environment * initDefaultEnvironment(
1102 const OUString & rEnvDcp, void * pContext )
1103{
1104 uno_Environment * pEnv = &(new uno_DefaultEnvironment( rEnvDcp, pContext ))->aBase;
1105 (*pEnv->acquire)( pEnv );
1106
1107 OUString envTypeName = cppu::EnvDcp::getTypeName(rEnvDcp);
1108
1109 // create default environment
1110 if ( envTypeName == UNO_LB_UNO"uno" )
1111 {
1112 uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
1113 that->computeObjectIdentifier = unoenv_computeObjectIdentifier;
1114 that->acquireInterface = unoenv_acquireInterface;
1115 that->releaseInterface = unoenv_releaseInterface;
1116
1117 OUString envPurpose = cppu::EnvDcp::getPurpose(rEnvDcp);
1118 if (!envPurpose.isEmpty())
1119 {
1120 rtl::OUString libStem = envPurpose.copy(envPurpose.lastIndexOf(':') + 1);
1121 libStem += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_uno_uno")(&("_uno_uno")[0]), ((sal_Int32)((sizeof ("_uno_uno") / sizeof
(("_uno_uno")[0]))-1)), (((rtl_TextEncoding) 11))
);
1122
1123 if(!loadEnv(libStem, pEnv))
1124 {
1125 pEnv->release(pEnv);
1126 return NULL__null;
1127 }
1128 }
1129 }
1130 else
1131 {
1132 // late init with some code from matching uno language binding
1133 ::rtl::OUStringBuffer aLibName( 16 );
1134 aLibName.append( envTypeName );
1135 aLibName.appendAscii( RTL_CONSTASCII_STRINGPARAM("_uno" )(&("_uno")[0]), ((sal_Int32)(sizeof ("_uno") / sizeof (("_uno"
)[0]))-1)
);
1136 OUString aStr( aLibName.makeStringAndClear() );
1137
1138 if (!loadEnv(aStr, pEnv))
1139 {
1140 pEnv->release(pEnv);
1141 return NULL__null;
1142 }
1143 }
1144
1145 return pEnv;
1146}
1147
1148//##############################################################################
1149CPPU_DLLPUBLIC__attribute__ ((visibility("default"))) void SAL_CALL uno_createEnvironment(
1150 uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
1151 SAL_THROW_EXTERN_C()throw ()
1152{
1153 OSL_ENSURE( ppEnv, "### null ptr!" )do { if (true && (!(ppEnv))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "1153" ": "), "%s", "### null ptr!"); } } while (false)
;
1154 if (*ppEnv)
1155 (*(*ppEnv)->release)( *ppEnv );
1156
1157 OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
1158 *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
1159}
1160
1161//##############################################################################
1162void SAL_CALL uno_direct_getEnvironment(
1163 uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
1164 SAL_THROW_EXTERN_C()throw ()
1165{
1166 OSL_ENSURE( ppEnv, "### null ptr!" )do { if (true && (!(ppEnv))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/uno/lbenv.cxx"
":" "1166" ": "), "%s", "### null ptr!"); } } while (false)
;
1167 OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
1168
1169 EnvironmentsData & rData = theEnvironmentsData::get();
1170
1171 ::osl::MutexGuard guard( rData.mutex );
1172 rData.getEnvironment( ppEnv, rEnvDcp, pContext );
1173 if (! *ppEnv)
1174 {
1175 *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
1176 if (*ppEnv)
1177 {
1178 // register new environment:
1179 rData.registerEnvironment( ppEnv );
1180 }
1181 }
1182}
1183
1184//##############################################################################
1185CPPU_DLLPUBLIC__attribute__ ((visibility("default"))) void SAL_CALL uno_getRegisteredEnvironments(
1186 uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
1187 rtl_uString * pEnvDcp )
1188 SAL_THROW_EXTERN_C()throw ()
1189{
1190 EnvironmentsData & rData = theEnvironmentsData::get();
1191
1192 ::osl::MutexGuard guard( rData.mutex );
1193 rData.getRegisteredEnvironments(
1194 pppEnvs, pnLen, memAlloc,
1195 (pEnvDcp ? OUString(pEnvDcp) : OUString()) );
1196}
1197
1198} // extern "C"
1199
1200}
1201
1202/* vim:set shiftwidth=4 softtabstop=4 expandtab: */