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