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