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