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