1 martin 1.59 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.60 //
|
3 martin 1.59 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.60 //
|
10 martin 1.59 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.60 //
|
17 martin 1.59 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.60 //
|
20 martin 1.59 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.60 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.59 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.60 //
|
28 martin 1.59 //////////////////////////////////////////////////////////////////////////
|
29 schuur 1.1 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
|
32 schuur 1.5 #include "CMPI_Version.h"
|
33 schuur 1.3
|
34 schuur 1.1 #include "CMPIProvider.h"
35
36 #include "CMPI_Object.h"
37 #include "CMPI_Broker.h"
38 #include "CMPI_ContextArgs.h"
39 #include "CMPI_Ftabs.h"
40
|
41 kumpf 1.30 #include <Pegasus/Common/Time.h>
|
42 schuur 1.1 #include <Pegasus/ProviderManager2/CMPI/CMPIProvider.h>
43 #include <Pegasus/ProviderManager2/CMPI/CMPIProviderModule.h>
|
44 konrad.r 1.22 #include <Pegasus/ProviderManager2/CMPI/CMPILocalProviderManager.h>
|
45 marek 1.63.2.3 #include <Pegasus/ProviderManager2/CMPI/CMPI_ThreadContext.h>
|
46 schuur 1.1
|
47 schuur 1.4 PEGASUS_USING_STD;
|
48 schuur 1.1 PEGASUS_NAMESPACE_BEGIN
49
|
50 venkat.puvvada 1.54 static const char _MSG_CANNOT_INIT_API_KEY[] =
51 "ProviderManager.CMPI.CMPIProvider.CANNOT_INIT_API";
|
52 kumpf 1.61 static const char _MSG_CANNOT_INIT_API[] =
|
53 venkat.puvvada 1.54 "Error initializing CMPI MI $0, the following MI"
54 " factory function(s) returned an error: $1";
55
56
|
57 schuur 1.1 // set current operations to 1 to prevent an unload
58 // until the provider has had a chance to initialize
|
59 venkat.puvvada 1.41 CMPIProvider::CMPIProvider(
60 const String & name,
|
61 thilo.boehm 1.63.2.4 const String & moduleName,
|
62 venkat.puvvada 1.39 CMPIProviderModule *module,
63 ProviderVector *mv)
|
64 marek 1.63.2.3 : _status(UNINITIALIZED), _module(module), _cimom_handle(0), _name(name),
|
65 thilo.boehm 1.63.2.4 _moduleName(moduleName), _no_unload(0), _threadWatchList(),
66 _cleanedThreads()
|
67 schuur 1.1 {
|
68 ms.aruran 1.44 PEG_METHOD_ENTER(
69 TRC_CMPIPROVIDERINTERFACE,
70 "CMPIProvider::CMPIProvider()");
|
71 venkat.puvvada 1.41 _current_operations = 1;
72 _currentSubscriptions = 0;
|
73 venkat.puvvada 1.54 _broker.hdl =0;
74 _broker.provider = this;
75 if (mv)
|
76 kumpf 1.61 {
|
77 venkat.puvvada 1.54 _miVector = *mv;
78 }
|
79 venkat.puvvada 1.45 unloadStatus = CMPI_RC_DO_NOT_UNLOAD;
|
80 venkat.puvvada 1.41 Time::gettimeofday(&_idleTime);
|
81 ms.aruran 1.44 PEG_METHOD_EXIT();
|
82 schuur 1.1 }
83
84 CMPIProvider::~CMPIProvider(void)
85 {
86 }
87
|
88 venkat.puvvada 1.41 CMPIProvider::Status CMPIProvider::getStatus()
|
89 schuur 1.1 {
|
90 dj.gorey 1.7 AutoMutex lock(_statusMutex);
|
91 schuur 1.1 return(_status);
92 }
93
|
94 venkat.puvvada 1.41 void CMPIProvider::set(
95 CMPIProviderModule *&module,
96 ProviderVector cmpiProvider,
97 CIMOMHandle *&cimomHandle)
|
98 dj.gorey 1.7 {
99 _module = module;
|
100 venkat.puvvada 1.54 _miVector = cmpiProvider;
|
101 dj.gorey 1.7 _cimom_handle = cimomHandle;
102 }
103
104 void CMPIProvider::reset()
105 {
106 _module = 0;
107 _cimom_handle = 0;
108 _no_unload = 0;
109 _status = UNINITIALIZED;
|
110 venkat.puvvada 1.55 unloadStatus = CMPI_RC_DO_NOT_UNLOAD;
|
111 dj.gorey 1.7 }
112
|
113 venkat.puvvada 1.41 CMPIProviderModule *CMPIProvider::getModule() const
|
114 schuur 1.1 {
115 return(_module);
116 }
117
|
118 thilo.boehm 1.63.2.4 String CMPIProvider::getModuleName() const
119 {
120 return _moduleName;
121 }
122
|
123 venkat.puvvada 1.41 String CMPIProvider::getName() const
|
124 schuur 1.1 {
|
125 konrad.r 1.20 return(_name.subString(1,PEG_NOT_FOUND));
126 }
|
127 venkat.puvvada 1.54
128 String CMPIProvider::getNameWithType() const
129 {
130 return(_name);
131 }
132
|
133 venkat.puvvada 1.41 void setError(
134 ProviderVector &miVector,
|
135 kumpf 1.56 String &errorMessage,
|
136 venkat.puvvada 1.41 const String &realProviderName,
137 const char *generic,
|
138 dave.sudlik 1.46 const char *spec,
139 const CMPIString *optMsg)
|
140 venkat.puvvada 1.41 {
|
141 ms.aruran 1.44 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPIProvider:setError()");
|
142 kumpf 1.56 if (errorMessage.size() > 0)
|
143 venkat.puvvada 1.41 {
|
144 kumpf 1.56 errorMessage.append("; ");
|
145 venkat.puvvada 1.41 }
|
146 dave.sudlik 1.46
147 String MItype;
|
148 venkat.puvvada 1.41 if (miVector.genericMode)
149 {
|
150 dave.sudlik 1.46 MItype.append(generic);
151 }
152 else
153 {
154 MItype.append(realProviderName);
155 MItype.append(spec);
156 }
157
|
158 dave.sudlik 1.47 if (optMsg && CMGetCharsPtr(optMsg,NULL))
|
159 dave.sudlik 1.46 {
160 MessageLoaderParms mlp(
161 "ProviderManager.CMPI.CMPIProvider.MESSAGE_WAS",
162 "$0, message was: $1",
163 MItype,
164 CMGetCharsPtr(optMsg,NULL));
165
|
166 kumpf 1.56 errorMessage.append(MessageLoader::getMessage(mlp));
|
167 venkat.puvvada 1.41 }
168 else
169 {
|
170 kumpf 1.56 errorMessage.append(MItype);
|
171 venkat.puvvada 1.41 }
|
172 ms.aruran 1.44 PEG_METHOD_EXIT();
|
173 venkat.puvvada 1.41 }
174
175 void CMPIProvider::initialize(
176 CIMOMHandle & cimom,
177 ProviderVector & miVector,
178 String & name,
179 CMPI_Broker & broker)
|
180 schuur 1.1 {
|
181 ms.aruran 1.44 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPIProvider::initialize()");
|
182 r.kieninger 1.63.2.2 broker.hdl=&cimom;
|
183 mark.hamzy 1.38 broker.bft=CMPI_Broker_Ftab;
184 broker.eft=CMPI_BrokerEnc_Ftab;
185 broker.xft=CMPI_BrokerExt_Ftab;
186 broker.mft=NULL; // CMPI memory services not supported
|
187 mark.hamzy 1.24
|
188 mark.hamzy 1.38 broker.name=name;
|
189 schuur 1.2
|
190 venkat.puvvada 1.54 miVector.instMI = NULL;
191 miVector.assocMI = NULL;
192 miVector.methMI = NULL;
193 miVector.propMI = NULL;
194 miVector.indMI = NULL;
|
195 schuur 1.1
|
196 ms.aruran 1.44 PEG_METHOD_EXIT();
|
197 schuur 1.1 }
198
199 void CMPIProvider::initialize(CIMOMHandle & cimom)
200 {
|
201 ms.aruran 1.44 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPIProvider::initialize()");
|
202 konrad.r 1.20 String providername(getName());
|
203 schuur 1.1
|
204 venkat.puvvada 1.41 if (_status == UNINITIALIZED)
205 {
206 String compoundName;
207 if (_location.size() == 0)
208 {
|
209 venkat.puvvada 1.54 compoundName = providername;
|
210 venkat.puvvada 1.41 }
|
211 venkat.puvvada 1.54 else
|
212 venkat.puvvada 1.41 {
|
213 venkat.puvvada 1.54 compoundName = _location + ":" + providername;
|
214 venkat.puvvada 1.41 }
|
215 venkat.puvvada 1.54 CMPIProvider::initialize(cimom,_miVector,compoundName,_broker);
|
216 venkat.puvvada 1.41 _status = INITIALIZED;
|
217 dj.gorey 1.7 _current_operations = 0;
|
218 venkat.puvvada 1.41 }
|
219 ms.aruran 1.44 PEG_METHOD_EXIT();
|
220 venkat.puvvada 1.41 }
221
222 Boolean CMPIProvider::tryTerminate()
223 {
|
224 ms.aruran 1.44 PEG_METHOD_ENTER(
225 TRC_CMPIPROVIDERINTERFACE,
226 "CMPIProvider::tryTerminate()");
227
|
228 venkat.puvvada 1.41 Boolean terminated = false;
229
230 if (_status == INITIALIZED)
231 {
232 if (false == unload_ok())
233 {
|
234 ms.aruran 1.44 PEG_METHOD_EXIT();
|
235 venkat.puvvada 1.41 return false;
236 }
237
238 Status savedStatus=_status;
239
240 try
241 {
|
242 venkat.puvvada 1.45 if (unloadStatus != CMPI_RC_OK)
|
243 venkat.puvvada 1.41 {
244 // False means that the CIMServer is not shutting down.
245 _terminate(false);
|
246 venkat.puvvada 1.45 if (unloadStatus != CMPI_RC_OK)
|
247 venkat.puvvada 1.41 {
248 _status=savedStatus;
|
249 ms.aruran 1.44 PEG_METHOD_EXIT();
|
250 venkat.puvvada 1.41 return false;
251 }
252 terminated=true;
253 }
254 }
255 catch (...)
256 {
|
257 thilo.boehm 1.57 PEG_TRACE((TRC_PROVIDERMANAGER,Tracer::LEVEL1,
258 "Exception caught in CMPIProviderFacade::tryTerminate() for %s",
259 (const char*)getName().getCString()));
|
260 venkat.puvvada 1.41 terminated = false;
261
262 }
263 if (terminated == true)
264 {
265 _status = UNINITIALIZED;
266 }
267 }
|
268 ms.aruran 1.44 PEG_METHOD_EXIT();
|
269 venkat.puvvada 1.41 return terminated;
|
270 schuur 1.1 }
271
|
272 konrad.r 1.22 /*
|
273 dave.sudlik 1.31 Terminates the CMPIProvider by cleaning its class cache and
|
274 konrad.r 1.22 calling its cleanup funtions.
275
276 @argument terminating When set to false, the provider may resist terminating.
|
277 venkat.puvvada 1.39 If true, provider MUST clean up.
|
278 dave.sudlik 1.31 */
|
279 konrad.r 1.16 void CMPIProvider::_terminate(Boolean terminating)
|
280 schuur 1.1 {
|
281 ms.aruran 1.44 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPIProvider::_terminate()");
|
282 schuur 1.1 const OperationContext opc;
283 CMPIStatus rc={CMPI_RC_OK,NULL};
284 CMPI_ContextOnStack eCtx(opc);
|
285 venkat.puvvada 1.54 CMPI_ThreadContext thr(&_broker,&eCtx);
|
286 konrad.r 1.16 /*
|
287 venkat.puvvada 1.39 @param terminating When true, the terminating argument indicates that the MB
288 is in the process of terminating and that cleanup must be done. When
289 set to false, the MI may respond with
290 CMPI_IRC_DO_NOT_UNLOAD, or CMPI_IRC_NEVER_UNLOAD,
291 indicating that unload will interfere with current MI processing.
292 @return Function return status. The following CMPIrc codes shall
293 be recognized:
|
294 konrad.r 1.16 CMPI_RC_OK Operation successful.
295 CMPI_RC_ERR_FAILED Unspecific error occurred.
296 CMPI_RC_DO_NOT_UNLOAD Operation successful - do not unload now.
297 CMPI_RC_NEVER_UNLOAD Operation successful - never unload.
298 */
|
299 dave.sudlik 1.48 unloadStatus = CMPI_RC_OK;
|
300 venkat.puvvada 1.54 if (_miVector.instMI)
|
301 venkat.puvvada 1.41 {
|
302 venkat.puvvada 1.54 rc=_miVector.instMI->ft->cleanup(_miVector.instMI,&eCtx, terminating);
|
303 venkat.puvvada 1.45 unloadStatus = rc.rc;
|
304 venkat.puvvada 1.41 }
|
305 venkat.puvvada 1.54 if (_miVector.assocMI)
|
306 venkat.puvvada 1.41 {
|
307 venkat.puvvada 1.54 rc=_miVector.assocMI->ft->cleanup(_miVector.assocMI,&eCtx, terminating);
|
308 venkat.puvvada 1.45 if (unloadStatus == CMPI_RC_OK)
|
309 venkat.puvvada 1.41 {
|
310 venkat.puvvada 1.45 unloadStatus = rc.rc;
|
311 venkat.puvvada 1.41 }
312 }
|
313 venkat.puvvada 1.54 if (_miVector.methMI)
|
314 venkat.puvvada 1.41 {
|
315 venkat.puvvada 1.54 rc=_miVector.methMI->ft->cleanup(_miVector.methMI,&eCtx, terminating);
|
316 venkat.puvvada 1.45 if (unloadStatus == CMPI_RC_OK)
|
317 venkat.puvvada 1.41 {
|
318 venkat.puvvada 1.45 unloadStatus = rc.rc;
|
319 venkat.puvvada 1.41 }
320 }
|
321 venkat.puvvada 1.54 if (_miVector.propMI)
|
322 venkat.puvvada 1.41 {
|
323 venkat.puvvada 1.54 rc=_miVector.propMI->ft->cleanup(_miVector.propMI,&eCtx, terminating);
|
324 venkat.puvvada 1.45 if (unloadStatus == CMPI_RC_OK)
|
325 venkat.puvvada 1.41 {
|
326 venkat.puvvada 1.45 unloadStatus = rc.rc;
|
327 venkat.puvvada 1.41 }
328 }
|
329 venkat.puvvada 1.54 if (_miVector.indMI)
|
330 venkat.puvvada 1.41 {
|
331 venkat.puvvada 1.54 rc=_miVector.indMI->ft->cleanup(_miVector.indMI,&eCtx, terminating);
|
332 venkat.puvvada 1.45 if (unloadStatus == CMPI_RC_OK)
|
333 venkat.puvvada 1.41 {
|
334 venkat.puvvada 1.45 unloadStatus = rc.rc;
|
335 venkat.puvvada 1.41 }
|
336 dave.sudlik 1.31 }
|
337 dave.sudlik 1.26
|
338 marek 1.52 if (unloadStatus == CMPI_RC_OK || terminating)
|
339 konrad.r 1.22 {
|
340 venkat.puvvada 1.41 // Check the thread list to make sure the thread has been de-allocated
341 if (_threadWatchList.size() != 0)
342 {
|
343 marek 1.53 PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
344 venkat.puvvada 1.41 "There are %d provider threads in %s that have to be cleaned "
345 "up.",
346 _threadWatchList.size(), (const char *)getName().getCString()));
347
348 // Walk through the list and terminate the threads. After they are
349 // terminated, put them back on the watch list, call the cleanup
350 // function and wait until the cleanup is completed.
351 while (_threadWatchList.size() > 0)
352 {
|
353 venkat.puvvada 1.39 // Remove the thread from the watch list and kill it.
|
354 mike 1.27 Thread *t = _threadWatchList.remove_front();
|
355 konrad.r 1.22
|
356 venkat.puvvada 1.41 /* If this a non-production build, DO NOT do the cancellation.
|
357 kumpf 1.61 This is done so that the provider developer will notice
358 incorrect behaviour when unloading his/her provider and
|
359 venkat.puvvada 1.41 hopefully fix that.
360 */
|
361 konrad.r 1.22 #if !defined(PEGASUS_DEBUG)
|
362 venkat.puvvada 1.41 # if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
363 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER,
364 Logger::WARNING,
365 "Provider thread in $0 did not exit after cleanup function."
366 " Attempting to terminate it.",
367 (const char *)getName().getCString());
|
368 venkat.puvvada 1.39 t->cancel();
|
369 venkat.puvvada 1.41 # else
370 // Every other OS that we do not want to do cancellation for.
371 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER,
372 Logger::WARNING,
373 "Provider thread in $0 did not exit after cleanup"
374 " function. Ignoring it.",
375 (const char *)getName().getCString());
376 # endif
|
377 dave.sudlik 1.31 #else
|
378 venkat.puvvada 1.41 // For the non-release
379 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER,
380 Logger::WARNING,
381 "Provider thread in $0 did not exit after cleanup"
382 " function. Ignoring it.",
383 (const char *)getName().getCString());
|
384 venkat.puvvada 1.39 // The cancellation is disabled so that when the join happends
385 // the CIMServer will hang. This should help the provider
386 // writer to fix his/her providers.
387 //t->cancel();
|
388 konrad.r 1.22 #endif
|
389 venkat.puvvada 1.39 // and perform the normal cleanup procedure
390 _threadWatchList.insert_back(t);
391 removeThreadFromWatch(t);
|
392 venkat.puvvada 1.41 }
|
393 venkat.puvvada 1.39 }
|
394 venkat.puvvada 1.41 // threadWatchList size ZERO doesn't mean that all threads have
395 // been cleaned-up. While unloading communication libraries,
396 // Threads waiting for MB UP calls might have
397 // just got removed from watchlist and not cleaned.
|
398 dave.sudlik 1.31
|
399 venkat.puvvada 1.41 // Wait until all of the threads have been cleaned.
400 waitUntilThreadsDone();
|
401 marek 1.51
|
402 konrad.r 1.22 }
|
403 marek 1.63.2.3 // We have killed all threads running in provider forcibly. Set
|
404 marek 1.62 // unloadStatus of provider to OK.
405 if (terminating)
406 {
407 unloadStatus = CMPI_RC_OK;
408 }
|
409 ms.aruran 1.44 PEG_METHOD_EXIT();
|
410 schuur 1.1 }
411
412
|
413 konrad.r 1.16 void CMPIProvider::terminate()
|
414 schuur 1.1 {
|
415 ms.aruran 1.44 PEG_METHOD_ENTER(
416 TRC_CMPIPROVIDERINTERFACE,
417 "CMPIProvider::terminate()");
|
418 venkat.puvvada 1.41 Status savedStatus=_status;
419 if (_status == INITIALIZED)
420 {
421 try
422 {
423
424 _terminate(true);
|
425 marek 1.62 PEGASUS_ASSERT(unloadStatus == CMPI_RC_OK);
|
426 venkat.puvvada 1.41 }
427 catch (...)
428 {
|
429 thilo.boehm 1.57 PEG_TRACE((TRC_PROVIDERMANAGER,Tracer::LEVEL1,
430 "Exception caught in CMPIProviderFacade::Terminate for %s",
431 (const char*)getName().getCString()));
|
432 venkat.puvvada 1.41 throw;
433 }
|
434 schuur 1.1 }
|
435 venkat.puvvada 1.63
436 // Provider's cleanup method called successfully, if there are still any
437 // pending operations with provider then we were asked to cleanup forcibly,
438 // don't uninitialize provider.
439 if (_current_operations.get() == 0)
440 {
441 _status = UNINITIALIZED;
442 }
443
|
444 ms.aruran 1.44 PEG_METHOD_EXIT();
|
445 schuur 1.1 }
446
|
447 konrad.r 1.22 /*
448 * Wait until all finished provider threads have been cleaned and deleted.
|
449 kumpf 1.61 * Note: This should NEVER be called from the thread that
450 * IS the Thread object that was is finished and called
|
451 venkat.puvvada 1.39 * 'removeThreadFromWatch()' . If you do it, you will
|
452 konrad.r 1.22 * wait forever.
453 */
|
454 ms.aruran 1.44 void CMPIProvider::waitUntilThreadsDone()
|
455 konrad.r 1.22 {
|
456 venkat.puvvada 1.39 while (_cleanedThreads.size() > 0)
457 {
458 Threads::yield();
459 }
|
460 konrad.r 1.22 }
461 /*
462 * Check if the Thread is owner by this CMPIProvider object.
463 *
464 * @argument t Thread that is not NULL.
465 */
|
466 ms.aruran 1.44 Boolean CMPIProvider::isThreadOwner(Thread *t)
|
467 konrad.r 1.22 {
|
468 venkat.puvvada 1.39 PEGASUS_ASSERT ( t != NULL );
|
469 venkat.puvvada 1.41 if (_cleanedThreads.contains(t))
|
470 ms.aruran 1.44 {
|
471 venkat.puvvada 1.39 return true;
|
472 ms.aruran 1.44 }
|
473 venkat.puvvada 1.41 if (!_threadWatchList.contains(t))
|
474 ms.aruran 1.44 {
|
475 venkat.puvvada 1.39 return true;
|
476 ms.aruran 1.44 }
|
477 venkat.puvvada 1.39 return false;
|
478 konrad.r 1.22 }
479 /*
480 * Remove the thread from the list of threads that are being deleted
481 * by the CMPILocalProviderManager.
482 *
|
483 venkat.puvvada 1.39 * @argument t Thread which has been previously provided
484 * to 'removeThreadFromWatch' function.
|
485 konrad.r 1.22 */
|
486 ms.aruran 1.44 void CMPIProvider::threadDelete(Thread *t)
|
487 konrad.r 1.22 {
|
488 venkat.puvvada 1.39 PEGASUS_ASSERT ( _cleanedThreads.contains(t) );
489 PEGASUS_ASSERT ( !_threadWatchList.contains(t) );
490 _cleanedThreads.remove( t );
|
491 konrad.r 1.22 }
492
|
493 venkat.puvvada 1.41 /*
494 // Removes the thread from the watch list and schedule the
|
495 kumpf 1.61 // CMPILocalProviderManager to delete the thread. The
|
496 venkat.puvvada 1.41 // CMPILocalProviderManager after deleting the thread calls
|
497 kumpf 1.61 // the CMPIProvider' "cleanupThread". The CMPILocalProviderManager
|
498 venkat.puvvada 1.41 // notifies this CMPIProvider object when the thread
499 // is truly dead by calling "threadDeleted" function.
500 //
501 // Note that this function is called from the thread that finished with
502 // running the providers function, and returns immediately while scheduling
503 // the a cleanup procedure. If you want to wait until the thread is truly
504 // deleted, call 'waitUntilThreadsDone' - but DO NOT do it in the the thread
505 // that the Thread owns - you will wait forever.
506 //
507 // @argument t Thread that is not NULL and finished with running
508 // the provider function.
509 */
|
510 ms.aruran 1.44 void CMPIProvider::removeThreadFromWatch(Thread *t)
|
511 konrad.r 1.22 {
|
512 ms.aruran 1.44 PEG_METHOD_ENTER(
513 TRC_CMPIPROVIDERINTERFACE,
514 "CMPIProvider::removeThreadFromWatch()");
|
515 venkat.puvvada 1.39 PEGASUS_ASSERT( t != 0 );
|
516 konrad.r 1.22
|
517 venkat.puvvada 1.58 // Note: After MI returned true from cleanup() method , there might be some
|
518 kumpf 1.61 // threads running in MI. CMPILocalProviderManager::cleanupThread() called
|
519 venkat.puvvada 1.58 // below will take care of joining the running threads in MI.
520 {
521 AutoMutex mtx(_removeThreadMutex);
522 if (_threadWatchList.contains(t))
523 {
524 // Remove it from the watched list
|
525 kumpf 1.61 _threadWatchList.remove(t);
|
526 venkat.puvvada 1.58 }
527 else
528 {
529 // This thread already has been removed from watch list.
530 PEG_METHOD_EXIT();
531 return;
532 }
533 }
534
|
535 venkat.puvvada 1.39 PEGASUS_ASSERT (!_cleanedThreads.contains (t));
|
536 konrad.r 1.22
|
537 dave.sudlik 1.31
|
538 venkat.puvvada 1.39 // Add the thread to the CMPIProvider's list.
539 // We use this list to keep track of threads that are
540 // being cleaned (this way 'waitUntilThreadsDone' can stall until the
541 // threads are truly deleted).
542 _cleanedThreads.insert_back(t);
|
543 konrad.r 1.22
|
544 venkat.puvvada 1.39 CMPILocalProviderManager::cleanupThread(t, this);
|
545 ms.aruran 1.44 PEG_METHOD_EXIT();
|
546 konrad.r 1.22 }
547
|
548 dave.sudlik 1.31 /*
|
549 konrad.r 1.22 * Adds the thread to the watch list. The watch list is monitored when the
550 * provider is terminated and if any of the threads have not cleaned up by
551 * that time, they are forcifully terminated and cleaned up.
552 *
553 * @argument t Thread is not NULL.
554 */
|
555 ms.aruran 1.44 void CMPIProvider::addThreadToWatch(Thread *t)
|
556 konrad.r 1.22 {
|
557 venkat.puvvada 1.39 PEGASUS_ASSERT( t != 0 );
|
558 konrad.r 1.22
|
559 mike 1.27 _threadWatchList.insert_back(t);
|
560 konrad.r 1.22 }
|
561 schuur 1.1
562 void CMPIProvider::get_idle_timer(struct timeval *t)
563 {
|
564 kumpf 1.30 PEGASUS_ASSERT(t != 0);
565 AutoMutex lock(_idleTimeMutex);
566 memcpy(t, &_idleTime, sizeof(struct timeval));
|
567 schuur 1.1 }
568
|
569 venkat.puvvada 1.41 void CMPIProvider::update_idle_timer()
|
570 schuur 1.1 {
|
571 kumpf 1.30 AutoMutex lock(_idleTimeMutex);
572 Time::gettimeofday(&_idleTime);
|
573 schuur 1.1 }
574
|
575 venkat.puvvada 1.45 /*
576 * This method returns "false" if there are any requests pending with
577 * the provider or Provider has returned CMPI_RC_NEVER_UNLOAD in the last
578 * cleanup() invocation cyle.
579 */
|
580 venkat.puvvada 1.41 Boolean CMPIProvider::unload_ok()
|
581 schuur 1.1 {
|
582 ms.aruran 1.44 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPIProvider::unload_ok()");
|
583 venkat.puvvada 1.45 if (unloadStatus == CMPI_RC_NEVER_UNLOAD)
|
584 ms.aruran 1.44 {
585 PEG_METHOD_EXIT();
586 return false;
587 }
|
588 venkat.puvvada 1.41 if (_no_unload.get())
|
589 ms.aruran 1.44 {
590 PEG_METHOD_EXIT();
|
591 venkat.puvvada 1.41 return false;
|
592 ms.aruran 1.44 }
|
593 kumpf 1.61 // Do not call CIMOMHandle::unload_ok here.
|
594 venkat.puvvada 1.42 // CIMOMHandle::unload_ok method tests for _providerUnloadProtect
595 // and if zero returns true. _providerUnloadProtect is
596 // incremented when CIMOMHandle::disallowProviderUnload()
597 // is called and decremented when
598 // CIMOMHandle::allowProviderUnload() is called. There is
599 // no way these functions are called from CMPI Providers.(Bug 6642)
|
600 ms.aruran 1.44 PEG_METHOD_EXIT();
|
601 venkat.puvvada 1.41 return true;
|
602 schuur 1.1 }
603
604 // force provider manager to keep in memory
|
605 venkat.puvvada 1.41 void CMPIProvider::protect()
|
606 dave.sudlik 1.31 {
|
607 venkat.puvvada 1.41 _no_unload++;
|
608 schuur 1.1 }
609
|
610 dave.sudlik 1.31 // allow provider manager to unload when idle
|
611 venkat.puvvada 1.41 void CMPIProvider::unprotect()
|
612 dave.sudlik 1.31 {
|
613 venkat.puvvada 1.41 _no_unload--;
|
614 schuur 1.1 }
615
|
616 carolann.graves 1.15 Boolean CMPIProvider::testIfZeroAndIncrementSubscriptions ()
617 {
618 AutoMutex lock (_currentSubscriptionsMutex);
619 Boolean isZero = (_currentSubscriptions == 0);
620 _currentSubscriptions++;
621
622 return isZero;
623 }
624
625 Boolean CMPIProvider::decrementSubscriptionsAndTestIfZero ()
626 {
627 AutoMutex lock (_currentSubscriptionsMutex);
628 _currentSubscriptions--;
629 Boolean isZero = (_currentSubscriptions == 0);
630
631 return isZero;
632 }
633
634 Boolean CMPIProvider::testSubscriptions ()
635 {
636 AutoMutex lock (_currentSubscriptionsMutex);
637 carolann.graves 1.15 Boolean currentSubscriptions = (_currentSubscriptions > 0);
638
639 return currentSubscriptions;
640 }
641
642 void CMPIProvider::resetSubscriptions ()
643 {
644 AutoMutex lock (_currentSubscriptionsMutex);
645 _currentSubscriptions = 0;
646 }
647
648 void CMPIProvider::setProviderInstance (const CIMInstance & instance)
649 {
650 _providerInstance = instance;
651 }
652
653 CIMInstance CMPIProvider::getProviderInstance ()
654 {
655 return _providerInstance;
656 }
657
|
658 venkat.puvvada 1.54 void CMPIProvider::incCurrentOperations ()
659 {
660 _current_operations++;
661 }
662
663 int CMPIProvider::getCurrentOperations ()
664 {
665 return _current_operations.get();
666 }
667
668 void CMPIProvider::decCurrentOperations ()
669 {
670 _current_operations--;
671 }
672
673 CIMOMHandle *CMPIProvider::getCIMOMHandle()
674 {
675 return _cimom_handle;
676 }
677
678 CMPI_Broker *CMPIProvider::getBroker()
679 venkat.puvvada 1.54 {
680 return &_broker;
681 }
682
683 CMPIInstanceMI *CMPIProvider::getInstMI()
684 {
685 if (_miVector.instMI == NULL)
686 {
687 AutoMutex mtx(_statusMutex);
688 if (_miVector.instMI == NULL)
689 {
690 const OperationContext opc;
691 CMPI_ContextOnStack eCtx(opc);
692 CMPIStatus rc = {CMPI_RC_OK, NULL};
693 String providerName = _broker.name;
694 CMPIInstanceMI *mi = NULL;
695
696 PEGASUS_ASSERT(_miVector.miTypes & CMPI_MIType_Instance);
697 if (_miVector.genericMode)
698 {
699 mi = _miVector.createGenInstMI(
700 venkat.puvvada 1.54 &_broker,
|
701 kumpf 1.61 &eCtx,
|
702 venkat.puvvada 1.54 (const char *)providerName.getCString(),
703 &rc);
704 }
|
705 kumpf 1.61 else
|
706 venkat.puvvada 1.54 {
707 mi = _miVector.createInstMI(&_broker, &eCtx, &rc);
708 }
709
|
710 kumpf 1.61 if (!mi || rc.rc != CMPI_RC_OK)
|
711 venkat.puvvada 1.54 {
712 String error;
713 setError(
714 _miVector,
715 error,
716 getName(),
717 _Generic_Create_InstanceMI,
718 _Create_InstanceMI,
719 rc.msg);
720
721 throw Exception(
722 MessageLoaderParms(
723 _MSG_CANNOT_INIT_API_KEY,
724 _MSG_CANNOT_INIT_API,
725 getName(),
726 error));
727 }
728 _miVector.instMI = mi;
729 }
|
730 kumpf 1.61 }
|
731 venkat.puvvada 1.54
732 return _miVector.instMI;
733 }
734
735 CMPIMethodMI *CMPIProvider::getMethMI()
736 {
737 if (_miVector.methMI == NULL)
738 {
739 AutoMutex mtx(_statusMutex);
740 if (_miVector.methMI == NULL)
741 {
742 const OperationContext opc;
743 CMPI_ContextOnStack eCtx(opc);
744 CMPIStatus rc = {CMPI_RC_OK, NULL};
745 String providerName = _broker.name;
746 CMPIMethodMI *mi;
747 PEGASUS_ASSERT(_miVector.miTypes & CMPI_MIType_Method);
|
748 kumpf 1.61 if (_miVector.genericMode)
|
749 venkat.puvvada 1.54 {
750 mi = _miVector.createGenMethMI(
751 &_broker,
|
752 kumpf 1.61 &eCtx,
|
753 venkat.puvvada 1.54 (const char *)providerName.getCString(),
754 &rc);
755 }
|
756 kumpf 1.61 else
|
757 venkat.puvvada 1.54 {
758 mi = _miVector.createMethMI(&_broker, &eCtx, &rc);
759 }
|
760 kumpf 1.61 if (!mi || rc.rc != CMPI_RC_OK)
|
761 venkat.puvvada 1.54 {
762 String error;
763 setError(
764 _miVector,
765 error,
766 getName(),
767 _Generic_Create_MethodMI,
768 _Create_MethodMI,
769 rc.msg);
770
771 throw Exception(
772 MessageLoaderParms(
773 _MSG_CANNOT_INIT_API_KEY,
774 _MSG_CANNOT_INIT_API,
775 getName(),
776 error));
777 }
778 _miVector.methMI = mi;
779 }
780 }
|
781 kumpf 1.61
|
782 venkat.puvvada 1.54 return _miVector.methMI;
783 }
784
785 CMPIAssociationMI *CMPIProvider::getAssocMI()
786 {
787 if (_miVector.assocMI == NULL)
788 {
789 AutoMutex mtx(_statusMutex);
790 if (_miVector.assocMI == NULL)
791 {
792 const OperationContext opc;
793 CMPI_ContextOnStack eCtx(opc);
794 CMPIStatus rc = {CMPI_RC_OK, NULL};
795 String providerName = _broker.name;
796 CMPIAssociationMI *mi;
797 PEGASUS_ASSERT(_miVector.miTypes & CMPI_MIType_Association);
798 if (_miVector.genericMode)
799 {
800 mi = _miVector.createGenAssocMI(
801 &_broker,
|
802 kumpf 1.61 &eCtx,
|
803 venkat.puvvada 1.54 (const char *)providerName.getCString(),
804 &rc);
|
805 kumpf 1.61 }
806 else
|
807 venkat.puvvada 1.54 {
808 mi = _miVector.createAssocMI(&_broker, &eCtx, &rc);
809 }
810
|
811 kumpf 1.61 if (!mi || rc.rc != CMPI_RC_OK)
|
812 venkat.puvvada 1.54 {
813 String error;
814 setError(
815 _miVector,
816 error,
817 getName(),
818 _Generic_Create_AssociationMI,
819 _Create_AssociationMI,
820 rc.msg);
821
822 throw Exception(
823 MessageLoaderParms(
824 _MSG_CANNOT_INIT_API_KEY,
825 _MSG_CANNOT_INIT_API,
826 getName(),
827 error));
828 }
829 _miVector.assocMI = mi;
830 }
831 }
|
832 kumpf 1.61
|
833 venkat.puvvada 1.54 return _miVector.assocMI;
834 }
835
836 CMPIPropertyMI *CMPIProvider::getPropMI()
837 {
838 if (_miVector.propMI == NULL)
839 {
840 AutoMutex mtx(_statusMutex);
841 if (_miVector.propMI == NULL)
842 {
843 const OperationContext opc;
844 CMPI_ContextOnStack eCtx(opc);
845 CMPIStatus rc = {CMPI_RC_OK, NULL};
846 String providerName = _broker.name;
847 CMPIPropertyMI *mi;
848 PEGASUS_ASSERT(_miVector.miTypes & CMPI_MIType_Property);
849
|
850 kumpf 1.61 if (_miVector.genericMode)
|
851 venkat.puvvada 1.54 {
852 mi = _miVector.createGenPropMI(
853 &_broker,
|
854 kumpf 1.61 &eCtx,
|
855 venkat.puvvada 1.54 (const char *)providerName.getCString(),
856 &rc);
857 }
|
858 kumpf 1.61 else
|
859 venkat.puvvada 1.54 {
860 mi = _miVector.createPropMI(&_broker, &eCtx, &rc);
861 }
862
863 if (!mi || rc.rc != CMPI_RC_OK)
864 {
865 String error;
866 setError(
867 _miVector,
868 error,
869 getName(),
870 _Generic_Create_PropertyMI,
871 _Create_PropertyMI,
872 rc.msg);
873
874 throw Exception(
875 MessageLoaderParms(
876 _MSG_CANNOT_INIT_API_KEY,
877 _MSG_CANNOT_INIT_API,
878 getName(),
879 error));
880 venkat.puvvada 1.54 }
881 _miVector.propMI = mi;
882 }
883 }
|
884 kumpf 1.61
|
885 venkat.puvvada 1.54 return _miVector.propMI;
886 }
887
888 CMPIIndicationMI *CMPIProvider::getIndMI()
889 {
890 if (_miVector.indMI == NULL)
891 {
892 AutoMutex mtx(_statusMutex);
893 if (_miVector.indMI == NULL)
894 {
895 const OperationContext opc;
896 CMPI_ContextOnStack eCtx(opc);
897 CMPIStatus rc = {CMPI_RC_OK, NULL};
898 String providerName = _broker.name;
899 CMPIIndicationMI *mi;
900 PEGASUS_ASSERT(_miVector.miTypes & CMPI_MIType_Indication);
901 if (_miVector.genericMode)
902 {
903 mi = _miVector.createGenIndMI(
904 &_broker,
|
905 kumpf 1.61 &eCtx,
|
906 venkat.puvvada 1.54 (const char *)providerName.getCString(),
907 &rc);
908 }
|
909 kumpf 1.61 else
|
910 venkat.puvvada 1.54 {
911 mi = _miVector.createIndMI(&_broker, &eCtx, &rc);
912 }
913
|
914 kumpf 1.61 if (!mi || rc.rc != CMPI_RC_OK)
|
915 venkat.puvvada 1.54 {
916 String error;
917 setError(
918 _miVector,
919 error,
920 getName(),
921 _Generic_Create_IndicationMI,
922 _Create_IndicationMI,
923 rc.msg);
924
925 throw Exception(
926 MessageLoaderParms(
927 _MSG_CANNOT_INIT_API_KEY,
928 _MSG_CANNOT_INIT_API,
929 getName(),
930 error));
931 }
932 _miVector.indMI = mi;
933 }
934 }
|
935 kumpf 1.61
|
936 venkat.puvvada 1.54 return _miVector.indMI;
937 }
938
939 CMPIProviderModule *CMPIProvider::getModule()
940 {
941 return _module;
942 }
943
944 Uint32 CMPIProvider::getQuantum()
945 {
|
946 kumpf 1.61 AutoMutex mutex(_statusMutex);
|
947 venkat.puvvada 1.54 return _quantum;
948 }
949
950 void CMPIProvider::setQuantum(Uint32 quantum)
951 {
|
952 kumpf 1.61 AutoMutex mutex(_statusMutex);
|
953 venkat.puvvada 1.54 _quantum = quantum;
954 }
955
956 Mutex &CMPIProvider::getStatusMutex()
957 {
958 return _statusMutex;
959 }
960
|
961 schuur 1.1 PEGASUS_NAMESPACE_END
|