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 + -
显示快捷键?