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
|