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