cmpiprovider.cpp
来自「Pegasus is an open-source implementation」· C++ 代码 · 共 610 行 · 第 1/2 页
CPP
610 行
@return Function return status. The following CMPIrc codes shall be recognized: CMPI_RC_OK Operation successful. CMPI_RC_ERR_FAILED Unspecific error occurred. CMPI_RC_DO_NOT_UNLOAD Operation successful - do not unload now. CMPI_RC_NEVER_UNLOAD Operation successful - never unload.*/ if (miVector.miTypes & CMPI_MIType_Instance) { rc=miVector.instMI->ft->cleanup(miVector.instMI,&eCtx, terminating); if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true; if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true; } if (miVector.miTypes & CMPI_MIType_Association) { rc=miVector.assocMI->ft->cleanup(miVector.assocMI,&eCtx, terminating); if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true; if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true; } if (miVector.miTypes & CMPI_MIType_Method) { rc=miVector.methMI->ft->cleanup(miVector.methMI,&eCtx, terminating); if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true; if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true; } if (miVector.miTypes & CMPI_MIType_Property) { rc=miVector.propMI->ft->cleanup(miVector.propMI,&eCtx, terminating); if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true; if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true; } if (miVector.miTypes & CMPI_MIType_Indication) { rc=miVector.indMI->ft->cleanup(miVector.indMI,&eCtx, terminating); if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true; if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true; } if (noUnload == false) { // Cleanup the class cache { WriteLock writeLock (broker.rwsemClassCache); if (broker.clsCache) { ClassCache::Iterator i=broker.clsCache->start(); for (; i; i++) { delete i.value(); } delete broker.clsCache; broker.clsCache=NULL; } } // Check the thread list to make sure the thread has been de-allocated if (_threadWatchList.size() != 0) { Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2, "There are %d provider threads in %s that have to be cleaned up.", _threadWatchList.size(), (const char *)getName().getCString()); // Walk through the list and terminate the threads. After they are // terminated, put them back on the watch list, call the cleanup function // and wait until the cleanup is completed. while (_threadWatchList.size() > 0) { // Remove the thread from the watch list and kill it. Thread *t = _threadWatchList.remove_front(); // If this a non-production build, DO NOT do the cancellation. This is // done so that the provider developer will notice incorrect behaviour // when unloading his/her provider and hopefully fix that.#if !defined(PEGASUS_DEBUG) #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING, "Provider thread in $0 did not exit after cleanup function. Attempting to terminate it.", (const char *)getName().getCString()); t->cancel(); #else // Every other OS that we do not want to do cancellation for. Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING, "Provider thread in $0 did not exit after cleanup function. Ignoring it.", (const char *)getName().getCString()); #endif#else // For the non-release Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING, "Provider thread in $0 did not exit after cleanup function. Ignoring it.", (const char *)getName().getCString()); // The cancellation is disabled so that when the join happends // the CIMServer will hang. This should help the provider writer to fix // his/her providers. //t->cancel();#endif // and perform the normal cleanup procedure _threadWatchList.insert_back(t); removeThreadFromWatch(t); } } // threadWatchList size ZERO doesn't mean that all threads have been cleaned-up. // While unloading communication libraries, Threads waiting for MB UP calls might have // just got removed from watchlist and not cleaned. // Wait until all of the threads have been cleaned. waitUntilThreadsDone(); }}void CMPIProvider::terminate(){ Status savedStatus=_status; if(_status == INITIALIZED) { // yield before a potentially lengthy operation. Threads::yield(); try { _terminate(true); if (noUnload==true) { _status=savedStatus; return; } } catch(...) { PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "Exception caught in CMPIProviderFacade::Terminate for " + getName()); throw; } } _status = UNINITIALIZED;}/* * Wait until all finished provider threads have been cleaned and deleted. * Note: This should NEVER be called from the thread that IS the Thread object that was * is finished and called 'removeThreadFromWatch()' . If you do it, you will * wait forever. */voidCMPIProvider::waitUntilThreadsDone(){ while (_cleanedThreads.size() > 0) { Threads::yield(); }}/* * Check if the Thread is owner by this CMPIProvider object. * * @argument t Thread that is not NULL. */BooleanCMPIProvider::isThreadOwner(Thread *t){ PEGASUS_ASSERT ( t != NULL ); if ( _cleanedThreads.contains(t) ) return true; if ( !_threadWatchList.contains(t) ) return true; return false;}/* * Remove the thread from the list of threads that are being deleted * by the CMPILocalProviderManager. * * @argument t Thread which has been previously provided to 'removeThreadFromWatch' function. */voidCMPIProvider::threadDelete(Thread *t){ PEGASUS_ASSERT ( _cleanedThreads.contains(t) ); PEGASUS_ASSERT ( !_threadWatchList.contains(t) ); _cleanedThreads.remove( t );} /* // Removes the thread from the watch list and schedule the CMPILocalProviderManager // to delete the thread. The CMPILocalProviderManager after deleting the thread calls // the CMPIProvider' "cleanupThread". The CMPILocalProviderManager notifies this // CMPIProvider object when the thread is truly dead by calling "threadDeleted" function. // // Note that this function is called from the thread that finished with // running the providers function, and returns immediately while scheduling the // a cleanup procedure. If you want to wait until the thread is truly deleted, // call 'waitUntilThreadsDone' - but DO NOT do it in the the thread that // the Thread owns - you will wait forever. // // @argument t Thread that is not NULL and finished with running the provider function. */voidCMPIProvider::removeThreadFromWatch(Thread *t){ PEGASUS_ASSERT( t != 0 ); PEGASUS_ASSERT (_threadWatchList.contains (t)); PEGASUS_ASSERT (!_cleanedThreads.contains (t)); // and remove it from the watched list _threadWatchList.remove(t); // Add the thread to the CMPIProvider's list. // We use this list to keep track of threads that are // being cleaned (this way 'waitUntilThreadsDone' can stall until the // threads are truly deleted). _cleanedThreads.insert_back(t); CMPILocalProviderManager::cleanupThread(t, this);}/* * Adds the thread to the watch list. The watch list is monitored when the * provider is terminated and if any of the threads have not cleaned up by * that time, they are forcifully terminated and cleaned up. * * @argument t Thread is not NULL.*/voidCMPIProvider::addThreadToWatch(Thread *t){ PEGASUS_ASSERT( t != 0 ); _threadWatchList.insert_back(t);}void CMPIProvider::get_idle_timer(struct timeval *t){ PEGASUS_ASSERT(t != 0); AutoMutex lock(_idleTimeMutex); memcpy(t, &_idleTime, sizeof(struct timeval));}void CMPIProvider::update_idle_timer(void){ AutoMutex lock(_idleTimeMutex); Time::gettimeofday(&_idleTime);}Boolean CMPIProvider::unload_ok(void){ if (noUnload==true) return false; if(_no_unload.get() ) return false; if(_cimom_handle) return _cimom_handle->unload_ok(); return true;}// force provider manager to keep in memoryvoid CMPIProvider::protect(void){ _no_unload++;}// allow provider manager to unload when idlevoid CMPIProvider::unprotect(void){ _no_unload--;}Boolean CMPIProvider::testIfZeroAndIncrementSubscriptions (){ AutoMutex lock (_currentSubscriptionsMutex); Boolean isZero = (_currentSubscriptions == 0); _currentSubscriptions++; return isZero;}Boolean CMPIProvider::decrementSubscriptionsAndTestIfZero (){ AutoMutex lock (_currentSubscriptionsMutex); _currentSubscriptions--; Boolean isZero = (_currentSubscriptions == 0); return isZero;}Boolean CMPIProvider::testSubscriptions (){ AutoMutex lock (_currentSubscriptionsMutex); Boolean currentSubscriptions = (_currentSubscriptions > 0); return currentSubscriptions;}void CMPIProvider::resetSubscriptions (){ AutoMutex lock (_currentSubscriptionsMutex); _currentSubscriptions = 0;}void CMPIProvider::setProviderInstance (const CIMInstance & instance){ _providerInstance = instance;}CIMInstance CMPIProvider::getProviderInstance (){ return _providerInstance;}PEGASUS_NAMESPACE_END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?