static dynamic_link_handle global_symbols_link( const wchar_t* library, const dynamic_link_descriptor descriptors[], size_t required ) { ::tbb::internal::suppress_unused_warning( library ); dynamic_link_handle library_handle; #if _WIN32 if ( GetModuleHandleEx( 0, library, &library_handle ) ) { if ( resolve_symbols( library_handle, descriptors, required ) ) return library_handle; else FreeLibrary( library_handle ); } #else /* _WIN32 */ #if !__TBB_DYNAMIC_LOAD_ENABLED /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */ if ( !dlopen ) return 0; #endif /* !__TBB_DYNAMIC_LOAD_ENABLED */ library_handle = dlopen( NULL, RTLD_LAZY ); #if !__ANDROID__ // On Android dlopen( NULL ) returns NULL if it is called during dynamic module initialization. LIBRARY_ASSERT( library_handle, "The handle for the main program is NULL" ); #endif // Check existence of the first symbol only, then use it to find the library and load all necessary symbols. pointer_to_handler handler; dynamic_link_descriptor desc; desc.name = descriptors[0].name; desc.handler = &handler; if ( resolve_symbols( library_handle, &desc, 1 ) ) return pin_symbols( library_handle, desc, descriptors, required ); #endif /* _WIN32 */ return 0; }
static dynamic_link_handle global_symbols_link( const char*, const dynamic_link_descriptor descriptors[], size_t required ) { #if __TBB_WEAK_SYMBOLS_PRESENT if ( !dlopen ) return 0; #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ dynamic_link_handle library_handle = dlopen( NULL, RTLD_LAZY ); #if __ANDROID__ // On Android dlopen( NULL ) returns NULL if it is called during dynamic module initialization. if ( !library_handle ) return 0; #endif // Check existence of only the first symbol, then use it to find the library and load all necessary symbols pointer_to_handler handler; dynamic_link_descriptor desc = { descriptors[0].name, &handler }; if ( resolve_symbols( library_handle, &desc, 1 ) ) return pin_symbols( desc, descriptors, required ); return 0; }
static dynamic_link_handle pin_symbols( dynamic_link_handle library_handle, dynamic_link_descriptor desc, const dynamic_link_descriptor* descriptors, size_t required ) { ::tbb::internal::suppress_unused_warning( desc, descriptors, required ); #if __TBB_DYNAMIC_LOAD_ENABLED // It is supposed that all symbols are from the only one library // The library has been loaded by another module and contains at least one requested symbol. // But after we obtained the symbol the library can be unloaded by another thread // invalidating our symbol. Therefore we need to pin the library in memory. const char * dli_fname; #ifdef __CYGWIN__ MEMORY_BASIC_INFORMATION mbi; char path[MAX_PATH]; VirtualQuery((void*)&dynamic_link, &mbi, sizeof(mbi)); if(GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH)) { char posix_path[MAX_PATH]; cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_RELATIVE, path, posix_path, MAX_PATH); dli_fname = posix_path; #else Dl_info info; // Get library's name from earlier found symbol if ( dladdr( (void*)*desc.handler, &info ) ) { dli_fname = info.dli_fname; #endif // Pin the library library_handle = dlopen( dli_fname, RTLD_LAZY ); if ( library_handle ) { // If original library was unloaded before we pinned it // and then another module loaded in its place, the earlier // found symbol would become invalid. So revalidate them. if ( !resolve_symbols( library_handle, descriptors, required ) ) { // Wrong library. dynamic_unlink(library_handle); library_handle = 0; } } else { char const * err = dlerror(); DYNAMIC_LINK_WARNING( dl_lib_not_found, dli_fname, err ); } } else { // The library have been unloaded by another thread library_handle = 0; } #endif /* __TBB_DYNAMIC_LOAD_ENABLED */ return library_handle; } #endif /* !_WIN32 */ static dynamic_link_handle global_symbols_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required ) { ::tbb::internal::suppress_unused_warning( library ); dynamic_link_handle library_handle; #if _WIN32 if ( GetModuleHandleEx( 0, library, &library_handle ) ) { if ( resolve_symbols( library_handle, descriptors, required ) ) return library_handle; else FreeLibrary( library_handle ); } #else /* _WIN32 */ #if !__TBB_DYNAMIC_LOAD_ENABLED /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */ if ( !dlopen ) return 0; #endif /* !__TBB_DYNAMIC_LOAD_ENABLED */ library_handle = dlopen( NULL, RTLD_LAZY ); #if !__ANDROID__ // On Android dlopen( NULL ) returns NULL if it is called during dynamic module initialization. LIBRARY_ASSERT( library_handle, "The handle for the main program is NULL" ); #endif // Check existence of the first symbol only, then use it to find the library and load all necessary symbols. pointer_to_handler handler; dynamic_link_descriptor desc; desc.name = descriptors[0].name; desc.handler = &handler; if ( resolve_symbols( library_handle, &desc, 1 ) ) return pin_symbols( library_handle, desc, descriptors, required ); #endif /* _WIN32 */ return 0; }