📄 defaultprovidermanager.cpp
字号:
PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Returning Provider " + providerName); PEG_METHOD_EXIT(); return poc;}ProviderMessageHandler* DefaultProviderManager::_lookupProvider( const String& providerName){ PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "DefaultProviderManager::_lookupProvider"); // lock the providerTable mutex AutoMutex lock(_providerTableMutex); // look up provider in cache ProviderMessageHandler* pr = 0; if (_providers.lookup(providerName, pr)) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Found Provider " + providerName + " in Provider Manager Cache"); } else { // create provider pr = new ProviderMessageHandler( providerName, 0, _indicationCallback, _responseChunkCallback, _subscriptionInitComplete); // insert provider in provider table _providers.insert(providerName, pr); PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Created provider " + pr->getName()); } PEG_METHOD_EXIT(); return pr;}ProviderMessageHandler* DefaultProviderManager::_initProvider( ProviderMessageHandler* provider, const String& moduleFileName){ PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "DefaultProviderManager::_initProvider"); ProviderModule* module = 0; CIMProvider* base; // lookup provider module module = _lookupModule(moduleFileName); // lock the provider status mutex AutoMutex lock(provider->status.getStatusMutex()); if (provider->status.isInitialized()) { // Initialization is already complete return provider; } PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Loading/Linking Provider Module " + moduleFileName); // load the provider try { base = module->load(provider->getName()); } catch (...) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Exception caught Loading/Linking Provider Module " + moduleFileName); PEG_METHOD_EXIT(); throw; } // initialize the provider PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, "Initializing Provider " + provider->getName()); CIMOMHandle* cimomHandle = new CIMOMHandle(); provider->status.setCIMOMHandle(cimomHandle); provider->status.setModule(module); provider->setProvider(base); Boolean initializeError = false; try { provider->initialize(*cimomHandle); } catch (...) { initializeError = true; } // The cleanup code executed when an exception occurs was previously // included in the catch block above. Unloading the provider module // from inside the catch block resulted in a crash when an exception // was thrown from a provider's initialize() method. The issue is that // when an exception is thrown, the program maintains internal // pointers related to the code that threw the exception. In the case // of an exception thrown from a provider during the initialize() // method, those pointers point into the provider library, so when // the DefaultProviderManager unloads the library, the pointers into // the library that the program was holding are invalid. if (initializeError == true) { // Allow the provider to clean up provider->terminate(); // delete the cimom handle delete cimomHandle; provider->setProvider(0); // unload provider module module->unloadModule(); } provider->status.setInitialized(!initializeError); PEG_METHOD_EXIT(); return provider;}ProviderModule* DefaultProviderManager::_lookupModule( const String& moduleFileName){ PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "DefaultProviderManager::_lookupModule"); // lock the providerTable mutex AutoMutex lock(_providerTableMutex); // look up provider module in cache ProviderModule* module = 0; if (_modules.lookup(moduleFileName, module)) { // found provider module in cache PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Found Provider Module " + moduleFileName + " in Provider Manager Cache"); } else { // provider module not found in cache, create provider module PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Creating Provider Module " + moduleFileName); module = new ProviderModule(moduleFileName); // insert provider module in module table _modules.insert(moduleFileName, module); } PEG_METHOD_EXIT(); return module;}Boolean DefaultProviderManager::hasActiveProviders(){ PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "DefaultProviderManager::hasActiveProviders"); try { AutoMutex lock(_providerTableMutex); Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Number of providers in _providers table = %d", _providers.size()); // Iterate through the _providers table looking for an active provider for (ProviderTable::Iterator i = _providers.start(); i != 0; i++) { if (i.value()->status.isInitialized()) { PEG_METHOD_EXIT(); return true; } } } catch (...) { // Unexpected exception; do not assume that no providers are loaded PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, "Unexpected Exception in hasActiveProviders."); PEG_METHOD_EXIT(); return true; } // No active providers were found in the _providers table PEG_METHOD_EXIT(); return false;}void DefaultProviderManager::unloadIdleProviders(){ PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "DefaultProviderManager::unloadIdleProviders"); try { struct timeval now; Time::gettimeofday(&now); // Make a copy of the table so it is not locked during provider calls Array<ProviderMessageHandler*> providerList; { AutoMutex lock(_providerTableMutex); for (ProviderTable::Iterator i = _providers.start(); i != 0; i++) { providerList.append(i.value()); } } for (Uint32 i = 0; i < providerList.size(); i++) { ProviderMessageHandler* provider = providerList[i]; AutoMutex lock(provider->status.getStatusMutex()); if (!provider->status.isInitialized()) { continue; } struct timeval providerTime = {0, 0}; provider->status.getLastOperationEndTime(&providerTime); PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "provider->status.isIdle() returns: " + CIMValue(provider->status.isIdle()).toString()); if (provider->status.isIdle() && ((now.tv_sec - providerTime.tv_sec) > ((Sint32)IDLE_LIMIT))) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, "Unloading idle provider: " + provider->getName()); _unloadProvider(provider); } } } catch (...) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, "Caught unexpected exception in unloadIdleProviders."); } PEG_METHOD_EXIT();}void DefaultProviderManager::_shutdownAllProviders(){ PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "DefaultProviderManager::_shutdownAllProviders"); try { AutoMutex lock(_providerTableMutex); Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "providers in cache = %d", _providers.size()); for (ProviderTable::Iterator i = _providers.start(); i != 0; i++) { ProviderMessageHandler* provider = i.value(); PEGASUS_ASSERT(provider != 0); AutoMutex lock(provider->status.getStatusMutex()); if (provider->status.isInitialized()) { _unloadProvider(provider); } } } catch (...) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Unexpected Exception in _shutdownAllProviders()."); } PEG_METHOD_EXIT();}Sint16 DefaultProviderManager::_disableProvider(const String& providerName){ PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "DefaultProviderManager::_disableProvider"); ProviderMessageHandler* pr = _lookupProvider(providerName); if (!pr->status.isInitialized()) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, "Provider " + providerName + " is not loaded"); PEG_METHOD_EXIT(); return 1; } PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Disable Provider " + pr->getName()); // // Check to see if there are pending requests. If there are pending // requests and the disable timeout has not expired, loop and wait one // second until either there is no pending requests or until timeout // expires. // Uint32 waitTime = PROVIDER_DISABLE_TIMEOUT; while ((pr->status.numCurrentOperations() > 0) && (waitTime > 0)) { Threads::sleep(1000); waitTime = waitTime - 1; } // There are still pending requests, do not disable if (pr->status.numCurrentOperations() > 0) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Disable failed since there are pending requests."); PEG_METHOD_EXIT(); return 0; } try { AutoMutex lock(pr->status.getStatusMutex()); if (pr->status.isInitialized()) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Unloading Provider " + pr->getName()); _unloadProvider(pr); } } catch (...) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Unload provider failed " + pr->getName()); PEG_METHOD_EXIT(); return -1; } PEG_METHOD_EXIT(); return 1;}void DefaultProviderManager::_unloadProvider(ProviderMessageHandler* provider){ // // NOTE: It is the caller's responsibility to make sure that the // provider->status.getStatusMutex() mutex is locked before calling // this method. // PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "DefaultProviderManager::_unloadProvider"); if (provider->status.numCurrentOperations() > 0) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Provider cannot be unloaded due to pending operations: " + provider->getName()); } else { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Terminating Provider " + provider->getName()); provider->terminate(); // unload provider module PEGASUS_ASSERT(provider->status.getModule() != 0); PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, "Unloading provider module: " + provider->getName()); provider->status.getModule()->unloadModule(); Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, "DefaultProviderManager: Unloaded provider $0", provider->getName()); // NOTE: The "delete provider->status.getCIMOMHandle()" operation // was moved to be called after the unloadModule() call above // as part of a fix for bugzilla 3669. For some providers // run out-of-process on Windows platforms (i.e. running // the cimserver with the forceProviderProcesses config option // set to "true"), deleting the provider's CIMOMHandle before // unloading the provider library caused the unload mechanism // to deadlock, making that provider unavailable and preventing // the cimserver from shutting down. It should NOT be moved back // above the unloadModule() call. See bugzilla 3669 for details. // delete the cimom handle PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Destroying provider's CIMOMHandle: " + provider->getName()); delete provider->status.getCIMOMHandle(); // set provider status to uninitialized provider->status.setInitialized(false); } PEG_METHOD_EXIT();}ProviderManager* DefaultProviderManager::createDefaultProviderManagerCallback(){ return new DefaultProviderManager();}PEGASUS_NAMESPACE_ENDPEGASUS_USING_PEGASUS;// This entry point is not needed because the DefaultProviderManager is created// using DefaultProviderManager::createDefaultProviderManagerCallback().#if 0extern "C" PEGASUS_EXPORT ProviderManager* PegasusCreateProviderManager( const String& providerManagerName){ if (String::equalNoCase(providerManagerName, "Default")) { return new DefaultProviderManager(); } return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -