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