1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_cppu.hxx" 30 31 #include "IdentityMapping.hxx" 32 33 #include <hash_map> 34 #include <set> 35 #include <algorithm> 36 37 #include "rtl/unload.h" 38 #include "rtl/ustring.hxx" 39 #include "rtl/ustrbuf.hxx" 40 #include "osl/module.h" 41 #include "osl/diagnose.h" 42 #include "osl/mutex.hxx" 43 #include "osl/interlck.h" 44 45 #include "uno/dispatcher.h" 46 #include "uno/mapping.h" 47 #include "uno/lbnames.h" 48 #include "uno/environment.hxx" 49 50 #include "typelib/typedescription.h" 51 52 #include "cppu/EnvDcp.hxx" 53 #include "cascade_mapping.hxx" 54 #include "IdentityMapping.hxx" 55 #include "loadmodule.hxx" 56 57 using namespace std; 58 using namespace osl; 59 using namespace rtl; 60 using namespace com::sun::star::uno; 61 62 63 namespace cppu 64 { 65 66 class Mapping 67 { 68 uno_Mapping * _pMapping; 69 70 public: 71 inline Mapping( uno_Mapping * pMapping = 0 ) SAL_THROW( () ); 72 inline Mapping( const Mapping & rMapping ) SAL_THROW( () ); 73 inline ~Mapping() SAL_THROW( () ); 74 inline Mapping & SAL_CALL operator = ( uno_Mapping * pMapping ) SAL_THROW( () ); 75 inline Mapping & SAL_CALL operator = ( const Mapping & rMapping ) SAL_THROW( () ) 76 { return operator = ( rMapping._pMapping ); } 77 inline uno_Mapping * SAL_CALL get() const SAL_THROW( () ) 78 { return _pMapping; } 79 inline sal_Bool SAL_CALL is() const SAL_THROW( () ) 80 { return (_pMapping != 0); } 81 }; 82 //__________________________________________________________________________________________________ 83 inline Mapping::Mapping( uno_Mapping * pMapping ) SAL_THROW( () ) 84 : _pMapping( pMapping ) 85 { 86 if (_pMapping) 87 (*_pMapping->acquire)( _pMapping ); 88 } 89 //__________________________________________________________________________________________________ 90 inline Mapping::Mapping( const Mapping & rMapping ) SAL_THROW( () ) 91 : _pMapping( rMapping._pMapping ) 92 { 93 if (_pMapping) 94 (*_pMapping->acquire)( _pMapping ); 95 } 96 //__________________________________________________________________________________________________ 97 inline Mapping::~Mapping() SAL_THROW( () ) 98 { 99 if (_pMapping) 100 (*_pMapping->release)( _pMapping ); 101 } 102 //__________________________________________________________________________________________________ 103 inline Mapping & Mapping::operator = ( uno_Mapping * pMapping ) SAL_THROW( () ) 104 { 105 if (pMapping) 106 (*pMapping->acquire)( pMapping ); 107 if (_pMapping) 108 (*_pMapping->release)( _pMapping ); 109 _pMapping = pMapping; 110 return *this; 111 } 112 113 //================================================================================================== 114 struct MappingEntry 115 { 116 sal_Int32 nRef; 117 uno_Mapping * pMapping; 118 uno_freeMappingFunc freeMapping; 119 OUString aMappingName; 120 121 MappingEntry( 122 uno_Mapping * pMapping_, uno_freeMappingFunc freeMapping_, 123 const OUString & rMappingName_ ) 124 SAL_THROW( () ) 125 : nRef( 1 ) 126 , pMapping( pMapping_ ) 127 , freeMapping( freeMapping_ ) 128 , aMappingName( rMappingName_ ) 129 {} 130 }; 131 //-------------------------------------------------------------------------------------------------- 132 struct FctOUStringHash : public unary_function< const OUString &, size_t > 133 { 134 size_t operator()( const OUString & rKey ) const SAL_THROW( () ) 135 { return (size_t)rKey.hashCode(); } 136 }; 137 //-------------------------------------------------------------------------------------------------- 138 struct FctPtrHash : public unary_function< uno_Mapping *, size_t > 139 { 140 size_t operator()( uno_Mapping * pKey ) const SAL_THROW( () ) 141 { return (size_t)pKey; } 142 }; 143 144 typedef hash_map< 145 OUString, MappingEntry *, FctOUStringHash, equal_to< OUString > > t_OUString2Entry; 146 typedef hash_map< 147 uno_Mapping *, MappingEntry *, FctPtrHash, equal_to< uno_Mapping * > > t_Mapping2Entry; 148 149 typedef set< uno_getMappingFunc > t_CallbackSet; 150 typedef set< OUString > t_OUStringSet; 151 152 //================================================================================================== 153 struct MappingsData 154 { 155 Mutex aMappingsMutex; 156 t_OUString2Entry aName2Entry; 157 t_Mapping2Entry aMapping2Entry; 158 159 Mutex aCallbacksMutex; 160 t_CallbackSet aCallbacks; 161 162 Mutex aNegativeLibsMutex; 163 t_OUStringSet aNegativeLibs; 164 }; 165 //-------------------------------------------------------------------------------------------------- 166 static MappingsData & getMappingsData() SAL_THROW( () ) 167 { 168 static MappingsData * s_p = 0; 169 if (! s_p) 170 { 171 MutexGuard aGuard( Mutex::getGlobalMutex() ); 172 if (! s_p) 173 { 174 //TODO This memory is leaked; see #i63473# for when this should be 175 // changed again: 176 s_p = new MappingsData; 177 } 178 } 179 return *s_p; 180 } 181 182 /** 183 * This class mediates two different mapping via uno, e.g. form any language to uno, 184 * then from uno to any other language. 185 */ 186 struct uno_Mediate_Mapping : public uno_Mapping 187 { 188 sal_Int32 nRef; 189 190 Environment aFrom; 191 Environment aTo; 192 193 Mapping aFrom2Uno; 194 Mapping aUno2To; 195 196 OUString aAddPurpose; 197 198 uno_Mediate_Mapping( 199 const Environment & rFrom_, const Environment & rTo_, 200 const Mapping & rFrom2Uno_, const Mapping & rUno2To_, 201 const OUString & rAddPurpose ) 202 SAL_THROW( () ); 203 }; 204 extern "C" 205 { 206 //-------------------------------------------------------------------------------------------------- 207 static void SAL_CALL mediate_free( uno_Mapping * pMapping ) 208 SAL_THROW( () ) 209 { 210 delete static_cast< uno_Mediate_Mapping * >( pMapping ); 211 } 212 //-------------------------------------------------------------------------------------------------- 213 static void SAL_CALL mediate_acquire( uno_Mapping * pMapping ) 214 SAL_THROW( () ) 215 { 216 if (1 == ::osl_incrementInterlockedCount( 217 & static_cast< uno_Mediate_Mapping * >( pMapping )->nRef )) 218 { 219 uno_registerMapping( 220 &pMapping, mediate_free, 221 static_cast< uno_Mediate_Mapping * >( pMapping )->aFrom.get(), 222 static_cast< uno_Mediate_Mapping * >( pMapping )->aTo.get(), 223 static_cast< uno_Mediate_Mapping * >( pMapping )->aAddPurpose.pData ); 224 } 225 } 226 //-------------------------------------------------------------------------------------------------- 227 static void SAL_CALL mediate_release( uno_Mapping * pMapping ) 228 SAL_THROW( () ) 229 { 230 if (! ::osl_decrementInterlockedCount( 231 & static_cast< uno_Mediate_Mapping * >( pMapping )->nRef )) 232 { 233 uno_revokeMapping( pMapping ); 234 } 235 } 236 //-------------------------------------------------------------------------------------------------- 237 static void SAL_CALL mediate_mapInterface( 238 uno_Mapping * pMapping, 239 void ** ppOut, void * pInterface, 240 typelib_InterfaceTypeDescription * pInterfaceTypeDescr ) 241 SAL_THROW( () ) 242 { 243 OSL_ENSURE( pMapping && ppOut, "### null ptr!" ); 244 if (pMapping && ppOut) 245 { 246 uno_Mediate_Mapping * that = static_cast< uno_Mediate_Mapping * >( pMapping ); 247 uno_Mapping * pFrom2Uno = that->aFrom2Uno.get(); 248 249 uno_Interface * pUnoI = 0; 250 (*pFrom2Uno->mapInterface)( pFrom2Uno, (void **) &pUnoI, pInterface, pInterfaceTypeDescr ); 251 if (0 == pUnoI) 252 { 253 void * pOut = *ppOut; 254 if (0 != pOut) 255 { 256 uno_ExtEnvironment * pTo = that->aTo.get()->pExtEnv; 257 OSL_ENSURE( 0 != pTo, "### cannot release out interface: leaking!" ); 258 if (0 != pTo) 259 (*pTo->releaseInterface)( pTo, pOut ); 260 *ppOut = 0; // set to 0 anyway, because mapping was not successfull! 261 } 262 } 263 else 264 { 265 uno_Mapping * pUno2To = that->aUno2To.get(); 266 (*pUno2To->mapInterface)( pUno2To, ppOut, pUnoI, pInterfaceTypeDescr ); 267 (*pUnoI->release)( pUnoI ); 268 } 269 } 270 } 271 } 272 //__________________________________________________________________________________________________ 273 uno_Mediate_Mapping::uno_Mediate_Mapping( 274 const Environment & rFrom_, const Environment & rTo_, 275 const Mapping & rFrom2Uno_, const Mapping & rUno2To_, 276 const OUString & rAddPurpose_ ) 277 SAL_THROW( () ) 278 : nRef( 1 ) 279 , aFrom( rFrom_ ) 280 , aTo( rTo_ ) 281 , aFrom2Uno( rFrom2Uno_ ) 282 , aUno2To( rUno2To_ ) 283 , aAddPurpose( rAddPurpose_ ) 284 { 285 uno_Mapping::acquire = mediate_acquire; 286 uno_Mapping::release = mediate_release; 287 uno_Mapping::mapInterface = mediate_mapInterface; 288 } 289 290 //================================================================================================== 291 static inline OUString getMappingName( 292 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) 293 SAL_THROW( () ) 294 { 295 OUStringBuffer aKey( 64 ); 296 aKey.append( rAddPurpose ); 297 aKey.append( (sal_Unicode)';' ); 298 aKey.append( rFrom.getTypeName() ); 299 aKey.append( (sal_Unicode)'[' ); 300 aKey.append( reinterpret_cast< sal_IntPtr >(rFrom.get()), 16 ); 301 aKey.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") ); 302 aKey.append( rTo.getTypeName() ); 303 aKey.append( (sal_Unicode)'[' ); 304 aKey.append( reinterpret_cast< sal_IntPtr >(rTo.get()), 16 ); 305 aKey.append( (sal_Unicode)']' ); 306 return aKey.makeStringAndClear(); 307 } 308 //================================================================================================== 309 static inline OUString getBridgeName( 310 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) 311 SAL_THROW( () ) 312 { 313 OUStringBuffer aBridgeName( 16 ); 314 if (rAddPurpose.getLength()) 315 { 316 aBridgeName.append( rAddPurpose ); 317 aBridgeName.append( (sal_Unicode)'_' ); 318 } 319 aBridgeName.append( EnvDcp::getTypeName(rFrom.getTypeName()) ); 320 aBridgeName.append( (sal_Unicode)'_' ); 321 aBridgeName.append( EnvDcp::getTypeName(rTo.getTypeName()) ); 322 return aBridgeName.makeStringAndClear(); 323 } 324 //================================================================================================== 325 static inline void setNegativeBridge( const OUString & rBridgeName ) 326 SAL_THROW( () ) 327 { 328 MappingsData & rData = getMappingsData(); 329 MutexGuard aGuard( rData.aNegativeLibsMutex ); 330 rData.aNegativeLibs.insert( rBridgeName ); 331 } 332 //================================================================================================== 333 static inline oslModule loadModule( const OUString & rBridgeName ) 334 SAL_THROW( () ) 335 { 336 sal_Bool bNeg; 337 { 338 MappingsData & rData = getMappingsData(); 339 MutexGuard aGuard( rData.aNegativeLibsMutex ); 340 const t_OUStringSet::const_iterator iFind( rData.aNegativeLibs.find( rBridgeName ) ); 341 bNeg = (iFind != rData.aNegativeLibs.end()); 342 } 343 344 if (! bNeg) 345 { 346 oslModule hModule = cppu::detail::loadModule( rBridgeName ); 347 348 if (hModule) 349 return hModule; 350 351 setNegativeBridge( rBridgeName ); // no load again 352 } 353 return 0; 354 } 355 //================================================================================================== 356 static Mapping loadExternalMapping( 357 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) 358 SAL_THROW( () ) 359 { 360 OSL_ASSERT( rFrom.is() && rTo.is() ); 361 if (rFrom.is() && rTo.is()) 362 { 363 // find proper lib 364 oslModule hModule = 0; 365 OUString aName; 366 367 if (EnvDcp::getTypeName(rFrom.getTypeName()).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) )) 368 hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) ); 369 if (! hModule) 370 hModule = loadModule( aName = getBridgeName( rFrom, rTo, rAddPurpose ) ); 371 if (! hModule) 372 hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) ); 373 374 if (hModule) 375 { 376 OUString aSymbolName( RTL_CONSTASCII_USTRINGPARAM(UNO_EXT_GETMAPPING) ); 377 uno_ext_getMappingFunc fpGetMapFunc = 378 (uno_ext_getMappingFunc)::osl_getFunctionSymbol( 379 hModule, aSymbolName.pData ); 380 381 if (fpGetMapFunc) 382 { 383 Mapping aExt; 384 (*fpGetMapFunc)( (uno_Mapping **)&aExt, rFrom.get(), rTo.get() ); 385 OSL_ASSERT( aExt.is() ); 386 if (aExt.is()) 387 { 388 ::rtl_registerModuleForUnloading( hModule ); 389 return aExt; 390 } 391 } 392 ::osl_unloadModule( hModule ); 393 setNegativeBridge( aName ); 394 } 395 } 396 return Mapping(); 397 } 398 399 //================================================================================================== 400 static Mapping getDirectMapping( 401 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose = OUString() ) 402 SAL_THROW( () ) 403 { 404 OSL_ASSERT( rFrom.is() && rTo.is() ); 405 if (rFrom.is() && rTo.is()) 406 { 407 MappingsData & rData = getMappingsData(); 408 ClearableMutexGuard aGuard( rData.aMappingsMutex ); 409 410 // try to find registered mapping 411 const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find( 412 getMappingName( rFrom, rTo, rAddPurpose ) ) ); 413 414 if (iFind == rData.aName2Entry.end()) 415 { 416 aGuard.clear(); 417 return loadExternalMapping( rFrom, rTo, rAddPurpose ); 418 } 419 else 420 { 421 return Mapping( (*iFind).second->pMapping ); 422 } 423 } 424 return Mapping(); 425 } 426 427 //-------------------------------------------------------------------------------------------------- 428 static inline Mapping createMediateMapping( 429 const Environment & rFrom, const Environment & rTo, 430 const Mapping & rFrom2Uno, const Mapping & rUno2To, 431 const OUString & rAddPurpose ) 432 SAL_THROW( () ) 433 { 434 uno_Mapping * pRet = new uno_Mediate_Mapping( 435 rFrom, rTo, rFrom2Uno, rUno2To, rAddPurpose ); // ref count initially 1 436 uno_registerMapping( 437 &pRet, mediate_free, rFrom.get(), rTo.get(), rAddPurpose.pData ); 438 Mapping aRet( pRet ); 439 (*pRet->release)( pRet ); 440 return aRet; 441 } 442 //================================================================================================== 443 static Mapping getMediateMapping( 444 const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose ) 445 SAL_THROW( () ) 446 { 447 Environment aUno; 448 Mapping aUno2To; 449 450 // backwards: from dest to source of mapping chain 451 452 // connect to uno 453 OUString aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ); 454 if (rTo.getTypeName() == aUnoEnvTypeName) // to is uno 455 { 456 aUno = rTo; 457 // no Uno2To mapping necessary 458 } 459 else 460 { 461 // get registered uno env 462 ::uno_getEnvironment( (uno_Environment **)&aUno, aUnoEnvTypeName.pData, 0 ); 463 464 aUno2To = getDirectMapping( aUno, rTo ); 465 // : uno <-> to 466 if (! aUno2To.is()) 467 return Mapping(); 468 } 469 470 // connect to uno 471 if (rAddPurpose.getLength()) // insert purpose mapping between new ano_uno <-> uno 472 { 473 // create anonymous uno env 474 Environment aAnUno; 475 ::uno_createEnvironment( (uno_Environment **)&aAnUno, aUnoEnvTypeName.pData, 0 ); 476 477 Mapping aAnUno2Uno( getDirectMapping( aAnUno, aUno, rAddPurpose ) ); 478 if (! aAnUno2Uno.is()) 479 return Mapping(); 480 481 if (aUno2To.is()) // to is not uno 482 { 483 // create another purposed mediate mapping 484 aUno2To = createMediateMapping( aAnUno, rTo, aAnUno2Uno, aUno2To, rAddPurpose ); 485 // : ano_uno <-> uno <-> to 486 } 487 else 488 { 489 aUno2To = aAnUno2Uno; 490 // : ano_uno <-> to (i.e., uno) 491 } 492 aUno = aAnUno; 493 } 494 495 Mapping aFrom2Uno( getDirectMapping( rFrom, aUno ) ); 496 if (aFrom2Uno.is() && aUno2To.is()) 497 { 498 return createMediateMapping( rFrom, rTo, aFrom2Uno, aUno2To, rAddPurpose ); 499 // : from <-> some uno ... 500 } 501 502 return Mapping(); 503 } 504 } 505 506 using namespace ::cppu; 507 508 extern "C" 509 { 510 //################################################################################################## 511 void SAL_CALL uno_getMapping( 512 uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo, 513 rtl_uString * pAddPurpose ) 514 SAL_THROW_EXTERN_C() 515 { 516 OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" ); 517 if (*ppMapping) 518 { 519 (*(*ppMapping)->release)( *ppMapping ); 520 *ppMapping = 0; 521 } 522 523 Mapping aRet; 524 Environment aFrom( pFrom ), aTo( pTo ); 525 526 OUString aAddPurpose; 527 if (pAddPurpose) 528 aAddPurpose = pAddPurpose; 529 530 MappingsData & rData = getMappingsData(); 531 532 // try registered mapping 533 { 534 MutexGuard aGuard( rData.aMappingsMutex ); 535 const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find( 536 getMappingName( aFrom, aTo, aAddPurpose ) ) ); 537 if (iFind != rData.aName2Entry.end()) 538 aRet = (*iFind).second->pMapping; 539 } 540 541 // See if an identity mapping does fit. 542 if (!aRet.is() && pFrom == pTo && !aAddPurpose.getLength()) 543 aRet = createIdentityMapping(pFrom); 544 545 if (!aRet.is()) 546 { 547 getCascadeMapping(ppMapping, pFrom, pTo, pAddPurpose); 548 549 if (*ppMapping) 550 return; 551 } 552 553 if (! aRet.is()) // try callback chain 554 { 555 MutexGuard aGuard( rData.aCallbacksMutex ); 556 for ( t_CallbackSet::const_iterator iPos( rData.aCallbacks.begin() ); 557 iPos != rData.aCallbacks.end(); ++iPos ) 558 { 559 (**iPos)( ppMapping, pFrom, pTo, aAddPurpose.pData ); 560 if (*ppMapping) 561 return; 562 } 563 } 564 565 if (! aRet.is()) 566 { 567 aRet = loadExternalMapping( aFrom, aTo, aAddPurpose ); // direct try 568 if (! aRet.is()) 569 aRet = getMediateMapping( aFrom, aTo, aAddPurpose ); // try via uno 570 } 571 572 if (aRet.is()) 573 { 574 (*aRet.get()->acquire)( aRet.get() ); 575 *ppMapping = aRet.get(); 576 } 577 } 578 //################################################################################################## 579 void SAL_CALL uno_getMappingByName( 580 uno_Mapping ** ppMapping, rtl_uString * pFrom, rtl_uString * pTo, 581 rtl_uString * pAddPurpose ) 582 SAL_THROW_EXTERN_C() 583 { 584 OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" ); 585 if (*ppMapping) 586 { 587 (*(*ppMapping)->release)( *ppMapping ); 588 *ppMapping = 0; 589 } 590 591 uno_Environment * pEFrom = 0; 592 uno_getEnvironment( &pEFrom, pFrom, 0 ); 593 OSL_ENSURE( pEFrom, "### cannot get source environment!" ); 594 if (pEFrom) 595 { 596 uno_Environment * pETo = 0; 597 uno_getEnvironment( &pETo, pTo, 0 ); 598 OSL_ENSURE( pETo, "### cannot get target environment!" ); 599 if (pETo) 600 { 601 ::uno_getMapping( ppMapping, pEFrom, pETo, pAddPurpose ); 602 (*pETo->release)( pETo ); 603 } 604 (*pEFrom->release)( pEFrom ); 605 } 606 } 607 608 //################################################################################################## 609 void SAL_CALL uno_registerMapping( 610 uno_Mapping ** ppMapping, uno_freeMappingFunc freeMapping, 611 uno_Environment * pFrom, uno_Environment * pTo, rtl_uString * pAddPurpose ) 612 SAL_THROW_EXTERN_C() 613 { 614 MappingsData & rData = getMappingsData(); 615 ClearableMutexGuard aGuard( rData.aMappingsMutex ); 616 617 const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( *ppMapping ) ); 618 if (iFind == rData.aMapping2Entry.end()) 619 { 620 OUString aMappingName( 621 getMappingName( pFrom, pTo, pAddPurpose ? OUString(pAddPurpose) : OUString() ) ); 622 #if OSL_DEBUG_LEVEL > 1 623 OString cstr( OUStringToOString( aMappingName, RTL_TEXTENCODING_ASCII_US ) ); 624 OSL_TRACE( "> inserting new mapping: %s", cstr.getStr() ); 625 #endif 626 // count initially 1 627 MappingEntry * pEntry = new MappingEntry( *ppMapping, freeMapping, aMappingName ); 628 rData.aName2Entry[ aMappingName ] = pEntry; 629 rData.aMapping2Entry[ *ppMapping ] = pEntry; 630 } 631 else 632 { 633 MappingEntry * pEntry = (*iFind).second; 634 ++pEntry->nRef; 635 636 if (pEntry->pMapping != *ppMapping) // exchange mapping to be registered 637 { 638 (*pEntry->pMapping->acquire)( pEntry->pMapping ); 639 --pEntry->nRef; // correct count; kill mapping to be registered 640 aGuard.clear(); 641 (*freeMapping)( *ppMapping ); 642 *ppMapping = pEntry->pMapping; 643 } 644 } 645 } 646 //################################################################################################## 647 void SAL_CALL uno_revokeMapping( 648 uno_Mapping * pMapping ) 649 SAL_THROW_EXTERN_C() 650 { 651 MappingsData & rData = getMappingsData(); 652 ClearableMutexGuard aGuard( rData.aMappingsMutex ); 653 654 const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( pMapping ) ); 655 OSL_ASSERT( iFind != rData.aMapping2Entry.end() ); 656 MappingEntry * pEntry = (*iFind).second; 657 if (! --pEntry->nRef) 658 { 659 rData.aMapping2Entry.erase( pEntry->pMapping ); 660 rData.aName2Entry.erase( pEntry->aMappingName ); 661 aGuard.clear(); 662 #if OSL_DEBUG_LEVEL > 1 663 OString cstr( OUStringToOString( pEntry->aMappingName, RTL_TEXTENCODING_ASCII_US ) ); 664 OSL_TRACE( "> revoking mapping %s", cstr.getStr() ); 665 #endif 666 (*pEntry->freeMapping)( pEntry->pMapping ); 667 delete pEntry; 668 } 669 } 670 671 //################################################################################################## 672 void SAL_CALL uno_registerMappingCallback( 673 uno_getMappingFunc pCallback ) 674 SAL_THROW_EXTERN_C() 675 { 676 OSL_ENSURE( pCallback, "### null ptr!" ); 677 MappingsData & rData = getMappingsData(); 678 MutexGuard aGuard( rData.aCallbacksMutex ); 679 rData.aCallbacks.insert( pCallback ); 680 } 681 //################################################################################################## 682 void SAL_CALL uno_revokeMappingCallback( 683 uno_getMappingFunc pCallback ) 684 SAL_THROW_EXTERN_C() 685 { 686 OSL_ENSURE( pCallback, "### null ptr!" ); 687 MappingsData & rData = getMappingsData(); 688 MutexGuard aGuard( rData.aCallbacksMutex ); 689 rData.aCallbacks.erase( pCallback ); 690 } 691 } // extern "C" 692 693