(file) Return to CMPIProvider.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / ProviderManager2 / CMPI

  1 karl  1.25 //%2006////////////////////////////////////////////////////////////////////////
  2 schuur 1.1  //
  3 karl   1.11 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4             // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5             // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6             // IBM Corp.; EMC Corporation, The Open Group.
  7             // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8             // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl   1.14 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10             // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl   1.25 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12             // EMC Corporation; Symantec Corporation; The Open Group.
 13 schuur 1.1  //
 14             // Permission is hereby granted, free of charge, to any person obtaining a copy
 15             // of this software and associated documentation files (the "Software"), to
 16             // deal in the Software without restriction, including without limitation the
 17             // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18             // sell copies of the Software, and to permit persons to whom the Software is
 19             // furnished to do so, subject to the following conditions:
 20 dave.sudlik 1.31 //
 21 schuur      1.1  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22                  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23                  // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24                  // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25                  // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26                  // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27                  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28                  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29                  //
 30                  //==============================================================================
 31                  //
 32                  //%/////////////////////////////////////////////////////////////////////////////
 33                  
 34 schuur      1.5  #include "CMPI_Version.h"
 35 schuur      1.3  
 36 schuur      1.1  #include "CMPIProvider.h"
 37                  
 38                  #include "CMPI_Object.h"
 39                  #include "CMPI_Broker.h"
 40                  #include "CMPI_ContextArgs.h"
 41                  #include "CMPI_Ftabs.h"
 42                  
 43                  #include <Pegasus/Common/Tracer.h>
 44 kumpf       1.30 #include <Pegasus/Common/Time.h>
 45 schuur      1.1  #include <Pegasus/ProviderManager2/CMPI/CMPIProvider.h>
 46                  #include <Pegasus/ProviderManager2/CMPI/CMPIProviderModule.h>
 47 konrad.r    1.22 #include <Pegasus/ProviderManager2/CMPI/CMPILocalProviderManager.h>
 48 schuur      1.1  
 49 schuur      1.4  PEGASUS_USING_STD;
 50 schuur      1.1  PEGASUS_NAMESPACE_BEGIN
 51                  
 52                  // set current operations to 1 to prevent an unload
 53                  // until the provider has had a chance to initialize
 54                  CMPIProvider::CMPIProvider(const String & name,
 55                  		   CMPIProviderModule *module,
 56                  		   ProviderVector *mv)
 57 schuur      1.9     : _status(UNINITIALIZED), _module(module), _cimom_handle(0), _name(name),
 58 mike        1.27      _no_unload(0), _rm(0), _threadWatchList(), _cleanedThreads()
 59 konrad.r    1.22 
 60 schuur      1.1  {
 61                     _current_operations = 1;
 62 carolann.graves 1.15    _currentSubscriptions = 0;
 63 konrad.r        1.20    broker.hdl =0;
 64 konrad.r        1.22    broker.provider = this;
 65 schuur          1.8     if (mv) miVector=*mv;
 66 dave.sudlik     1.31    noUnload=false;
 67 kumpf           1.30    Time::gettimeofday(&_idleTime);
 68 schuur          1.1  }
 69                      
 70                      CMPIProvider::CMPIProvider(CMPIProvider *pr)
 71 schuur          1.9    : _status(UNINITIALIZED), _module(pr->_module), _cimom_handle(0), _name(pr->_name),
 72 mike            1.27     _no_unload(0), _rm(0), _threadWatchList(), _cleanedThreads()
 73 schuur          1.1  {
 74                         _current_operations = 1;
 75 carolann.graves 1.15    _currentSubscriptions = 0;
 76 schuur          1.1     miVector=pr->miVector;
 77 konrad.r        1.20    broker.hdl =0;
 78 konrad.r        1.22    broker.provider = this;
 79 schuur          1.1     _cimom_handle=new CIMOMHandle();
 80 dave.sudlik     1.31    noUnload=pr->noUnload;
 81 kumpf           1.30    Time::gettimeofday(&_idleTime);
 82 schuur          1.1  }
 83                      
 84                      CMPIProvider::~CMPIProvider(void)
 85                      {
 86                      }
 87                      
 88 dj.gorey        1.7  CMPIProvider::Status CMPIProvider::getStatus(void)
 89 schuur          1.1  {
 90 dj.gorey        1.7      AutoMutex lock(_statusMutex);
 91 schuur          1.1      return(_status);
 92                      }
 93                      
 94 dj.gorey        1.7  void CMPIProvider::set(CMPIProviderModule *&module,
 95                                          ProviderVector cmpiProvider,
 96                                          CIMOMHandle *&cimomHandle)
 97                      {
 98                          _module = module;
 99                          miVector = cmpiProvider;
100                          _cimom_handle = cimomHandle;
101                      }
102                      
103                      void CMPIProvider::reset()
104                      {
105                          _module = 0;
106                          _cimom_handle = 0;
107                          _no_unload = 0;
108                          _status = UNINITIALIZED;
109                      }
110                      
111 schuur          1.1  CMPIProviderModule *CMPIProvider::getModule(void) const
112                      {
113                          return(_module);
114                      }
115                      
116                      String CMPIProvider::getName(void) const
117                      {
118 konrad.r        1.20     return(_name.subString(1,PEG_NOT_FOUND));
119                      }
120                      void setError(ProviderVector &miVector,
121                                      String &error,
122                      		const String &realProviderName,
123                                        const char *generic,
124 dave.sudlik     1.31                   const char *spec)
125 konrad.r        1.20 {
126                      
127                         if (miVector.genericMode)
128                                 error.append(generic);
129                         else
130                            {
131                                 error.append(realProviderName);
132                                 error.append(spec);
133                            }
134                        error.append(", ");
135 schuur          1.1  }
136                      
137                      void CMPIProvider::initialize(CIMOMHandle & cimom,
138                                                    ProviderVector & miVector,
139                      			      String & name,
140                                                    CMPI_Broker & broker)
141                      {
142 marek           1.32.6.1         broker.hdl=& cimom;
143 schuur          1.1              broker.bft=CMPI_Broker_Ftab;
144                                  broker.eft=CMPI_BrokerEnc_Ftab;
145 schuur          1.9              broker.xft=CMPI_BrokerExt_Ftab;
146 dave.sudlik     1.32             broker.mft=NULL;    // CMPI memory services not supported
147 mark.hamzy      1.24             {
148                                      WriteLock writeLock (broker.rwsemClassCache);
149                          
150                                      broker.clsCache=new ClassCache();
151                                  }
152 schuur          1.1              broker.name=name;
153 schuur          1.2      
154 schuur          1.1              const OperationContext opc;
155                                  CMPI_ContextOnStack eCtx(opc);
156 marek           1.13             CMPI_ThreadContext thr(&broker,&eCtx);
157 konrad.r        1.16     	    CMPIStatus rc = {CMPI_RC_OK, NULL};
158 konrad.r        1.20     		String error = String::EMPTY;
159                            	    String realProviderName(name);
160 schuur          1.1      
161                                  if (miVector.genericMode) {
162 marek           1.19                CString mName=realProviderName.getCString();
163 schuur          1.1                 if (miVector.miTypes & CMPI_MIType_Instance)
164 konrad.r        1.16                   miVector.instMI=miVector.createGenInstMI(&broker,&eCtx,mName, &rc);
165 schuur          1.1                 if (miVector.miTypes & CMPI_MIType_Association)
166 konrad.r        1.16                   miVector.assocMI=miVector.createGenAssocMI(&broker,&eCtx,mName, &rc);
167 dave.sudlik     1.31                if (miVector.miTypes & CMPI_MIType_Method)
168 konrad.r        1.16                   miVector.methMI=miVector.createGenMethMI(&broker,&eCtx,mName, &rc);
169 schuur          1.1                 if (miVector.miTypes & CMPI_MIType_Property)
170 konrad.r        1.16                   miVector.propMI=miVector.createGenPropMI(&broker,&eCtx,mName, &rc);
171 schuur          1.1                 if (miVector.miTypes & CMPI_MIType_Indication)
172 konrad.r        1.16                   miVector.indMI=miVector.createGenIndMI(&broker,&eCtx,mName, &rc);
173 schuur          1.1              }
174                                  else {
175                                     if (miVector.miTypes & CMPI_MIType_Instance)
176 konrad.r        1.16                   miVector.instMI=miVector.createInstMI(&broker,&eCtx, &rc);
177 schuur          1.1                 if (miVector.miTypes & CMPI_MIType_Association)
178 konrad.r        1.16                   miVector.assocMI=miVector.createAssocMI(&broker,&eCtx, &rc);
179 dave.sudlik     1.31                if (miVector.miTypes & CMPI_MIType_Method)
180 konrad.r        1.16                   miVector.methMI=miVector.createMethMI(&broker,&eCtx, &rc);
181 schuur          1.1                 if (miVector.miTypes & CMPI_MIType_Property)
182 konrad.r        1.16                   miVector.propMI=miVector.createPropMI(&broker,&eCtx, &rc);
183 schuur          1.1                 if (miVector.miTypes & CMPI_MIType_Indication)
184 konrad.r        1.16                   miVector.indMI=miVector.createIndMI(&broker,&eCtx, &rc);
185 schuur          1.1              }
186 dave.sudlik     1.31     
187 konrad.r        1.20                if (miVector.miTypes & CMPI_MIType_Instance)
188                                        if (miVector.instMI == NULL || rc.rc != CMPI_RC_OK)
189                          			setError(miVector, error, realProviderName, _Generic_Create_InstanceMI, _Create_InstanceMI);
190                                     if (miVector.miTypes & CMPI_MIType_Association)
191                                        if (miVector.assocMI == NULL || rc.rc != CMPI_RC_OK)
192                          			setError(miVector, error, realProviderName, _Generic_Create_AssociationMI, _Create_AssociationMI);
193 dave.sudlik     1.31                if (miVector.miTypes & CMPI_MIType_Method)
194 konrad.r        1.20                   if (miVector.methMI == NULL || rc.rc != CMPI_RC_OK)
195                          			setError(miVector, error, realProviderName, _Generic_Create_MethodMI, _Create_MethodMI);
196                                     if (miVector.miTypes & CMPI_MIType_Property)
197                          			 if (miVector.propMI == NULL || rc.rc != CMPI_RC_OK)
198                          			setError(miVector, error, realProviderName, _Generic_Create_PropertyMI, _Create_PropertyMI);
199                                     if (miVector.miTypes & CMPI_MIType_Indication)
200                                        if (miVector.indMI == NULL || rc.rc != CMPI_RC_OK)
201                          			setError(miVector, error, realProviderName, _Generic_Create_IndicationMI, _Create_IndicationMI);
202                          
203 dave.sudlik     1.31     		if (error.size() != 0)
204 konrad.r        1.20     		 {
205                          		    	throw Exception(MessageLoaderParms("ProviderManager.CMPI.CMPIProvider.CANNOT_INIT_API",
206                                      			"ProviderInitFailure: Error initializing $0 the following API(s): $1",
207                          				realProviderName,
208                          				error.subString(0, error.size()-2)));
209                          		  }
210 schuur          1.1      }
211                          
212                          void CMPIProvider::initialize(CIMOMHandle & cimom)
213                          {
214 konrad.r        1.20         String providername(getName());
215 schuur          1.1      
216 dj.gorey        1.7          if(_status == UNINITIALIZED)
217                            {
218 konrad.r        1.12           String compoundName;
219                                if (_location.size() == 0)
220 marek           1.17     			compoundName= providername;
221 konrad.r        1.12           else
222 marek           1.17     			compoundName=_location+":"+providername;
223 schuur          1.9            try {
224                          	 // yield before a potentially lengthy operation.
225 mike            1.29             Threads::yield();
226 schuur          1.9      	 CMPIProvider::initialize(cimom,miVector,compoundName,broker);
227 dj.gorey        1.7      	      if (miVector.miTypes & CMPI_MIType_Method) {
228                          	        if (miVector.methMI->ft->miName==NULL) noUnload=true;
229                          	      }
230                                }
231 schuur          1.9            catch(...) {
232 dj.gorey        1.7              _current_operations = 0;
233                          	      throw;
234                                }
235                                _status = INITIALIZED;
236                                _current_operations = 0;
237                            }
238 schuur          1.1      }
239                          
240                          Boolean CMPIProvider::tryTerminate(void)
241                          {
242 dj.gorey        1.7        Boolean terminated = false;
243                          
244                            if(_status == INITIALIZED)
245 dave.sudlik     1.31       {
246 schuur          1.1         if(false == unload_ok())
247                             {
248                                return false;
249                             }
250                          
251                             Status savedStatus=_status;
252                          
253                                // yield before a potentially lengthy operation.
254 mike            1.29           Threads::yield();
255 schuur          1.1            try
256                                {
257                          	if (noUnload==false) {
258 konrad.r        1.16     		// False means that the CIMServer is not shutting down.
259                          	   _terminate(false);
260 schuur          1.1      	   if (noUnload==true) {
261                          	      _status=savedStatus;
262                          	      return false;
263                          	   }
264                          	   terminated=true;
265 dj.gorey        1.7      	 }
266 schuur          1.1            }
267                                catch(...)
268                                {
269 dj.gorey        1.7      	 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
270 schuur          1.1      			  "Exception caught in CMPIProviderFacade::tryTerminate() for " +
271 konrad.r        1.20     			  getName());
272 schuur          1.1      	 terminated = false;
273 dave.sudlik     1.31     
274 schuur          1.1            }
275 dj.gorey        1.7         if(terminated == true)
276 dave.sudlik     1.31        {
277 dj.gorey        1.7          _status = UNINITIALIZED;
278 schuur          1.1         }
279 dj.gorey        1.7        }
280                            return terminated;
281 schuur          1.1      }
282                          
283 konrad.r        1.22     /*
284 dave.sudlik     1.31      Terminates the CMPIProvider by cleaning its class cache and
285 konrad.r        1.22      calling its cleanup funtions.
286                          
287                           @argument terminating When set to false, the provider may resist terminating.
288                            	If true, provider MUST clean up.
289 dave.sudlik     1.31     */
290 konrad.r        1.16     void CMPIProvider::_terminate(Boolean terminating)
291 schuur          1.1      {
292                              const OperationContext opc;
293                              CMPIStatus rc={CMPI_RC_OK,NULL};
294                              CMPI_ContextOnStack eCtx(opc);
295 marek           1.13         CMPI_ThreadContext thr(&broker,&eCtx);
296 konrad.r        1.16     /*
297                           @param terminating When true, the terminating argument indicates that the MB is in the process of
298                               terminating and that cleanup must be done. When set to false, the MI may respond with
299                               CMPI_IRC_DO_NOT_UNLOAD, or CMPI_IRC_NEVER_UNLOAD, indicating that unload will
300                               interfere with current MI processing.
301                               @return Function return status. The following CMPIrc codes shall be recognized:
302                                  CMPI_RC_OK Operation successful.
303                                  CMPI_RC_ERR_FAILED Unspecific error occurred.
304                                  CMPI_RC_DO_NOT_UNLOAD Operation successful - do not unload now.
305                                  CMPI_RC_NEVER_UNLOAD Operation successful - never unload.
306                          */
307 schuur          1.1          if (miVector.miTypes & CMPI_MIType_Instance) {
308 konrad.r        1.18            rc=miVector.instMI->ft->cleanup(miVector.instMI,&eCtx, terminating);
309 schuur          1.1             if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true;
310 konrad.r        1.16     	   if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true;
311 dave.sudlik     1.31         }
312 schuur          1.1          if (miVector.miTypes & CMPI_MIType_Association) {
313 konrad.r        1.18            rc=miVector.assocMI->ft->cleanup(miVector.assocMI,&eCtx, terminating);
314 schuur          1.1             if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true;
315 konrad.r        1.16     	   if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true;
316 dave.sudlik     1.31         }
317 schuur          1.1          if (miVector.miTypes & CMPI_MIType_Method) {
318 konrad.r        1.18            rc=miVector.methMI->ft->cleanup(miVector.methMI,&eCtx, terminating);
319 schuur          1.1             if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true;
320 konrad.r        1.16     	   if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true;
321 dave.sudlik     1.31         }
322 schuur          1.1          if (miVector.miTypes & CMPI_MIType_Property) {
323 konrad.r        1.18            rc=miVector.propMI->ft->cleanup(miVector.propMI,&eCtx, terminating);
324 schuur          1.1             if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true;
325 konrad.r        1.16     	   if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true;
326 dave.sudlik     1.31         }
327 schuur          1.1          if (miVector.miTypes & CMPI_MIType_Indication) {
328 konrad.r        1.18            rc=miVector.indMI->ft->cleanup(miVector.indMI,&eCtx, terminating);
329 schuur          1.1             if (rc.rc==CMPI_RC_ERR_NOT_SUPPORTED) noUnload=true;
330 konrad.r        1.16     	   if ((rc.rc == CMPI_RC_DO_NOT_UNLOAD) || (rc.rc==CMPI_RC_NEVER_UNLOAD)) noUnload =true;
331 dave.sudlik     1.31         }
332 dave.sudlik     1.26     
333 dave.sudlik     1.31         if (noUnload == false)
334 konrad.r        1.22         {
335 dave.sudlik     1.26             // Cleanup the class cache
336                                  {
337                                     WriteLock writeLock (broker.rwsemClassCache);
338                          
339                                     if (broker.clsCache) {
340                                        ClassCache::Iterator i=broker.clsCache->start();
341                                        for (; i; i++) {
342                                           delete i.value();
343                                        }
344                                        delete broker.clsCache;
345                                        broker.clsCache=NULL;
346                                     }
347                                  }
348                          
349 konrad.r        1.22     	  // Check the thread list to make sure the thread has been de-allocated
350                          	  if (_threadWatchList.size() != 0)
351                          	  {
352                          	 	Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
353                          			  "There are %d provider threads in %s that have to be cleaned up.",
354                          			_threadWatchList.size(), (const char *)getName().getCString());
355 dave.sudlik     1.31     
356                          		// Walk through the list and terminate the threads. After they are
357 konrad.r        1.22     		// terminated, put them back on the watch list, call the cleanup function
358                          		// and wait until the cleanup is completed.
359 mike            1.27     		while (_threadWatchList.size() > 0) {
360 konrad.r        1.22     				// Remove the thread from the watch list and kill it.
361 mike            1.27                     Thread *t = _threadWatchList.remove_front();
362 konrad.r        1.22     
363 dave.sudlik     1.31     		// If this a non-production build, DO NOT do the cancellation. This is
364 konrad.r        1.22     		// done so that the provider developer will notice incorrect behaviour
365                          		// when unloading his/her provider and hopefully fix that.
366                          #if !defined(PEGASUS_DEBUG)
367                          	#if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
368 dave.sudlik     1.31     	 			Logger::put(Logger::STANDARD_LOG, System::CIMSERVER,
369 konrad.r        1.22     							Logger::WARNING,
370                          							"Provider thread in $0 did not exit after cleanup function. Attempting to terminate it.",
371                          					 		(const char *)getName().getCString());
372                          				t->cancel();
373                          	#else
374                          	// Every other OS that we do not want to do cancellation for.
375 dave.sudlik     1.31     	 			Logger::put(Logger::STANDARD_LOG, System::CIMSERVER,
376 konrad.r        1.22     							Logger::WARNING,
377                          			  				"Provider thread in $0 did not exit after cleanup function. Ignoring it.",
378                          					 		(const char *)getName().getCString());
379                          	#endif
380 dave.sudlik     1.31     #else
381 konrad.r        1.22     	// For the non-release
382 dave.sudlik     1.31     	 			Logger::put(Logger::STANDARD_LOG, System::CIMSERVER,
383 konrad.r        1.22     							Logger::WARNING,
384                          			  				"Provider thread in $0 did not exit after cleanup function. Ignoring it.",
385                          					 		(const char *)getName().getCString());
386                          				// The cancellation is disabled so that when the join happends
387 dave.sudlik     1.31     				// the CIMServer will hang. This should help the provider writer to fix
388 konrad.r        1.22     				// his/her providers.
389                          				//t->cancel();
390                          #endif
391                          				//  and perform the normal  cleanup procedure
392 mike            1.27     				_threadWatchList.insert_back(t);
393 dave.sudlik     1.31     				removeThreadFromWatch(t);
394 konrad.r        1.22     		}
395                          	  }
396 dave.sudlik     1.31               // threadWatchList size ZERO doesn't mean that all threads have been cleaned-up.
397                                    // While unloading communication libraries, Threads waiting for MB UP calls might have
398                                    // just got removed from watchlist and not cleaned.
399                          
400                                    // Wait until all of the threads have been cleaned.
401                                    waitUntilThreadsDone();
402 konrad.r        1.22         }
403 schuur          1.1      }
404                          
405                          
406 konrad.r        1.16     void CMPIProvider::terminate()
407 schuur          1.1      {
408 dave.sudlik     1.31       Status savedStatus=_status;
409 dj.gorey        1.7        if(_status == INITIALIZED)
410                            {
411                          	  // yield before a potentially lengthy operation.
412 mike            1.29     	  Threads::yield();
413 dave.sudlik     1.31     	  try
414 schuur          1.1          {
415 dave.sudlik     1.31     
416 konrad.r        1.22             _terminate(true);
417 dj.gorey        1.7      	      if (noUnload==true) {
418 schuur          1.1                  _status=savedStatus;
419 dj.gorey        1.7      	          return;
420                          	      }
421                              }
422                                  catch(...)
423                              {
424 dave.sudlik     1.31     	      PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
425                          			       "Exception caught in CMPIProviderFacade::Terminate for " +
426 konrad.r        1.20     			       getName());
427 dj.gorey        1.7            throw;
428 schuur          1.1          }
429 dj.gorey        1.7        }
430                            _status = UNINITIALIZED;
431 schuur          1.1      }
432                          
433 konrad.r        1.22     /*
434                           * Wait until all finished provider threads have been cleaned and deleted.
435                           * Note: This should NEVER be called from the thread that IS the Thread object that was
436                           * is finished and called 'removeThreadFromWatch()' . If you do it, you will
437                           * wait forever.
438                           */
439 dave.sudlik     1.31     void
440 konrad.r        1.22     CMPIProvider::waitUntilThreadsDone()
441                          {
442                          	while (_cleanedThreads.size() > 0)
443                          	{
444 mike            1.29     		Threads::yield();
445 konrad.r        1.22     	}
446                          }
447                          /*
448                           * Check if the Thread is owner by this CMPIProvider object.
449                           *
450                           * @argument t Thread that is not NULL.
451                           */
452                          Boolean
453 dave.sudlik     1.31     CMPIProvider::isThreadOwner(Thread *t)
454 konrad.r        1.22     {
455                          	PEGASUS_ASSERT ( t != NULL );
456 mike            1.27     	if  ( _cleanedThreads.contains(t) )
457 konrad.r        1.22     		return true;
458 mike            1.27     	if  ( !_threadWatchList.contains(t) )
459 konrad.r        1.22     		return true;
460                          
461                          	return false;
462                          }
463                          /*
464                           * Remove the thread from the list of threads that are being deleted
465                           * by the CMPILocalProviderManager.
466                           *
467                           * @argument t Thread which has been previously provided to 'removeThreadFromWatch' function.
468                           */
469                          void
470                          CMPIProvider::threadDelete(Thread *t)
471                          {
472 mike            1.27     	PEGASUS_ASSERT ( _cleanedThreads.contains(t) );
473                          	PEGASUS_ASSERT ( !_threadWatchList.contains(t) );
474 konrad.r        1.22     	_cleanedThreads.remove( t );
475                          }
476                          
477                            /*
478                            // Removes the thread from the watch list and schedule the CMPILocalProviderManager
479                            // to delete the thread. The CMPILocalProviderManager after deleting the thread calls
480                            // the CMPIProvider' "cleanupThread". The CMPILocalProviderManager notifies this
481                            // CMPIProvider object when the thread is truly dead by calling "threadDeleted" function.
482                            //
483                            // Note that this function is called from the thread that finished with
484                            // running the providers function, and returns immediately while scheduling the
485                            // a cleanup procedure. If you want to wait until the thread is truly deleted,
486                            // call 'waitUntilThreadsDone' - but DO NOT do it in the the thread that
487                            // the Thread owns - you will wait forever.
488                            //
489                            // @argument t Thread that is not NULL and finished with running the provider function.
490                            */
491 dave.sudlik     1.31     void
492 konrad.r        1.22     CMPIProvider::removeThreadFromWatch(Thread *t)
493                          {
494                          	PEGASUS_ASSERT( t != 0 );
495                          
496 mike            1.27     	PEGASUS_ASSERT (_threadWatchList.contains (t));
497                          	PEGASUS_ASSERT (!_cleanedThreads.contains (t));
498 konrad.r        1.22     
499 mike            1.27     	// and remove it from the watched list
500                          	_threadWatchList.remove(t);
501 dave.sudlik     1.31     
502 konrad.r        1.22     	// Add the thread to the CMPIProvider's list.
503 dave.sudlik     1.31     	// We use this list to keep track of threads that are
504 konrad.r        1.22     	// being cleaned (this way 'waitUntilThreadsDone' can stall until the
505 dave.sudlik     1.31     	// threads are truly deleted).
506 mike            1.27     	_cleanedThreads.insert_back(t);
507 konrad.r        1.22     
508                          	CMPILocalProviderManager::cleanupThread(t, this);
509                          }
510                          
511 dave.sudlik     1.31     /*
512 konrad.r        1.22      * Adds the thread to the watch list. The watch list is monitored when the
513                           * provider is terminated and if any of the threads have not cleaned up by
514                           * that time, they are forcifully terminated and cleaned up.
515                           *
516                           * @argument t Thread is not NULL.
517                          */
518 dave.sudlik     1.31     void
519 konrad.r        1.22     CMPIProvider::addThreadToWatch(Thread *t)
520                          {
521                          	PEGASUS_ASSERT( t != 0 );
522                          
523 mike            1.27         _threadWatchList.insert_back(t);
524 konrad.r        1.22     }
525 schuur          1.1      
526                          void CMPIProvider::get_idle_timer(struct timeval *t)
527                          {
528 kumpf           1.30         PEGASUS_ASSERT(t != 0);
529                              AutoMutex lock(_idleTimeMutex);
530                              memcpy(t, &_idleTime, sizeof(struct timeval));
531 schuur          1.1      }
532                          
533                          void CMPIProvider::update_idle_timer(void)
534                          {
535 kumpf           1.30         AutoMutex lock(_idleTimeMutex);
536                              Time::gettimeofday(&_idleTime);
537 schuur          1.1      }
538                          
539                          Boolean CMPIProvider::unload_ok(void)
540                          {
541                             if (noUnload==true) return false;
542 mike            1.23        if(_no_unload.get() )
543 schuur          1.1            return false;
544 dave.sudlik     1.31     
545 schuur          1.1         if(_cimom_handle)
546                                return _cimom_handle->unload_ok();
547                             return true;
548                          }
549                          
550                          //   force provider manager to keep in memory
551                          void CMPIProvider::protect(void)
552 dave.sudlik     1.31     {
553 schuur          1.1         _no_unload++;
554                          }
555                          
556 dave.sudlik     1.31     // allow provider manager to unload when idle
557 schuur          1.1      void CMPIProvider::unprotect(void)
558 dave.sudlik     1.31     {
559 schuur          1.1         _no_unload--;
560                          }
561                          
562 carolann.graves 1.15     Boolean CMPIProvider::testIfZeroAndIncrementSubscriptions ()
563                          {
564                              AutoMutex lock (_currentSubscriptionsMutex);
565                              Boolean isZero = (_currentSubscriptions == 0);
566                              _currentSubscriptions++;
567                          
568                              return isZero;
569                          }
570                          
571                          Boolean CMPIProvider::decrementSubscriptionsAndTestIfZero ()
572                          {
573                              AutoMutex lock (_currentSubscriptionsMutex);
574                              _currentSubscriptions--;
575                              Boolean isZero = (_currentSubscriptions == 0);
576                          
577                              return isZero;
578                          }
579                          
580                          Boolean CMPIProvider::testSubscriptions ()
581                          {
582                              AutoMutex lock (_currentSubscriptionsMutex);
583 carolann.graves 1.15         Boolean currentSubscriptions = (_currentSubscriptions > 0);
584                          
585                              return currentSubscriptions;
586                          }
587                          
588                          void CMPIProvider::resetSubscriptions ()
589                          {
590                              AutoMutex lock (_currentSubscriptionsMutex);
591                              _currentSubscriptions = 0;
592                          }
593                          
594                          void CMPIProvider::setProviderInstance (const CIMInstance & instance)
595                          {
596                              _providerInstance = instance;
597                          }
598                          
599                          CIMInstance CMPIProvider::getProviderInstance ()
600                          {
601                              return _providerInstance;
602                          }
603                          
604 schuur          1.1      PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2