57 schuur 1.1 }
58
59 Sint32 CMPILocalProviderManager::_provider_ctrl(CTRL code, void *parm, void *ret)
60 {
61
62 static Uint32 quantum;
63 auto_mutex monitor(&_mut);
64 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "_provider_ctrl");
65
66 Sint32 ccode = 0;
67 CTRL_STRINGS *parms = reinterpret_cast<CTRL_STRINGS *>(parm);
68
69 switch(code)
70 {
71
72 case GET_PROVIDER:
73 {
74
75 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
76 "_provider_ctrl::GET_PROVIDER");
77
78 schuur 1.1 CMPIProvider *pr = NULL;
79 CMPIProvider::OpProviderHolder* ph =
80 reinterpret_cast< CMPIProvider::OpProviderHolder* >( ret );
81
82
83 if(true == _providers.lookup( *(parms->providerName), pr ))
84 {
85 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
86 "Found CMPIProvider " + *(parms->providerName) + " in CMPIProvider Manager Cache");
87
88 ph->SetProvider( pr );
89 ph->GetProvider().update_idle_timer();
90 break;
91 }
92
93
94 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
95 "Creating CMPIProvider " + *(parms->providerName) );
96 CMPIProviderModule *module;
97
98 if(false == _modules.lookup(*(parms->fileName), module))
99 schuur 1.1 {
100 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
101 "Creating CMPIProvider Module " + *(parms->fileName) );
102
103 module = new CMPIProviderModule(*(parms->fileName),*(parms->interfaceName));
104
105 _modules.insert((*parms->fileName), module);
106 }
107 else
108 {
109 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
110 "Using Cached CMPIProvider Module " + *(parms->fileName) );
111 }
112
113
114 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
115 "Loading/Linking CMPIProvider Module " + *(parms->fileName) );
116
117 ProviderVector base ;
118 try
119 {
120 schuur 1.1 base = module->load(*(parms->providerName));
121 }
122 catch(...)
123 {
124 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
125 "Exception caught Loading/Linking CMPIProvider Module " + *(parms->fileName) );
126 throw;
127
128 //<< Wed Jul 30 17:43:05 2003 mdd >> bugzilla 286
129 // now just propogate the exception.
130 // if this causes problems, fix it in the ProviderManagerService, which should be able to catch this exception
131 // CIMNullProvider *dummy = new CIMNullProvider();
132 // if(dummy == 0)
133 // {
134 // throw NullPointer();
135 // }
136 // base = static_cast<CIMProvider *>(dummy);
137 }
138
139 // create provider module
140
141 schuur 1.1 MessageQueue * queue = MessageQueue::lookup(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
142 PEGASUS_ASSERT(queue != 0);
143 MessageQueueService * service = dynamic_cast<MessageQueueService *>(queue);
144 PEGASUS_ASSERT(service != 0);
145 pr = new CMPIProvider(*(parms->providerName), module, &base);
146 if(0 == (pr->_cimom_handle = new CIMOMHandle()))
147 throw NullPointer();
148 pr->_quantum=0;
149
150
151 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
152 "Loading CMPIProvider " + pr->_name);
153 try
154 {
155 pr->initialize(*(pr->_cimom_handle));
156 }
157 catch(...)
158 {
159 delete pr->_cimom_handle;
160 delete pr;
161 throw UninitializedObjectException();
162 schuur 1.1 }
163
164 pr->update_idle_timer();
165
166 _providers.insert(*(parms->providerName), pr);
167
168
169 ph->SetProvider( pr );
170 break;
171 }
172
173 case UNLOAD_PROVIDER:
174 {
175
176 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
177 "_provider_ctrl::UNLOAD_PROVIDER");
178 CTRL_STRINGS *parms = reinterpret_cast<CTRL_STRINGS *>(parm);
179 CMPIProvider *pr;
180 if(true == _providers.lookup(*(parms->providerName), pr ))
181 {
182 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
183 schuur 1.1 "Unloading CMPIProvider " + pr->_name );
184 if(pr->_current_operations.value())
185 {
186 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
187 "CMPIProvider cannot be unloaded due to pending operations: " +
188 pr->_name );
189 break;
190 }
191 _providers.remove(pr->_name);
192 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
193 "Terminating CMPIProvider " + pr->_name );
194 try
195 {
196 pr->terminate();
197 }
198 catch(...)
199 {
200
201 }
202
203 if((pr->_module != 0 ) && pr->_module->_ref_count.value() == 0)
204 schuur 1.1 {
205 _modules.remove(pr->_module->_fileName);
206 try
207 {
208 pr->_module->unloadModule();
209 }
210 catch(...)
211 {
212
213 }
214 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
215 "Destroying CMPIProvider " + pr->_name );
216
217 delete pr->_module;
218 }
219
220 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
221 "Destroying CMPIProvider's CIMOM Handle " + pr->_name );
222
223 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
224 "ProviderManager::_provider_crtl - Unload provider $0",
225 schuur 1.1 pr->_name);
226
227 delete pr->_cimom_handle;
228 delete pr;
229 }
230 else
231 {
232 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
233 "Unable to find CMPIProvider in cache: " +
234 *(parms->providerName));
235 }
236 break;
237 }
238
239 case LOOKUP_PROVIDER:
240 {
241
242 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
243 "_provider_ctrl::LOOKUP_PROVIDER");
244
245 if(true == _providers.lookup(*(parms->providerName),
246 schuur 1.1 *(reinterpret_cast<CMPIProvider * *>(ret))))
247 {
248 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
249 "Found CMPIProvider in cache: " +
250 *(parms->providerName));
251
252 (*(reinterpret_cast<CMPIProvider * *>(ret)))->update_idle_timer();
253 }
254 else
255 {
256
257 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
258 "Could not find CMPIProvider in cache: " +
259 *(parms->providerName));
260 ccode = -1;
261 }
262
263 break;
264 }
265
266 case LOOKUP_MODULE:
267 schuur 1.1 {
268
269 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
270 "_provider_ctrl::LOOKUP_MODULE");
271
272 if(false == _modules.lookup(*(parms->fileName),
273 *(reinterpret_cast<CMPIProviderModule * *>(ret))))
274 {
275 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
276 "Could not find CMPIProvider Module in cache: " +
277 *(parms->fileName));
278 ccode = -1;
279 }
280
281 break;
282 }
283
284 case INSERT_PROVIDER:
285 {
286
287 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
288 schuur 1.1 "_provider_ctrl::INSERT_PROVIDER");
289 if(false == _providers.insert(
290 *(parms->providerName),
291 *reinterpret_cast<CMPIProvider * *>(parm)))
292 ccode = -1;
293 break;
294 }
295 case INSERT_MODULE:
296 {
297 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
298 "_provider_ctrl::INSERT_MODULE");
299 if(false == _modules.insert(
300 *(parms->fileName),
301 *reinterpret_cast<CMPIProviderModule * *>(parm)))
302 ccode = -1;
303 break;
304 }
305 case REMOVE_PROVIDER:
306 {
307
308 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
309 schuur 1.1 "_provider_ctrl::REMOVE_PROVIDER");
310 if(false == _providers.remove(*(parms->providerName)))
311 ccode = -1;
312 break;
313 }
314 case REMOVE_MODULE:
315 {
316
317 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
318 "_provider_ctrl::REMOVE_MODULE");
319 if(false == _modules.remove(*(parms->fileName)))
320 ccode = -1;
321 break;
322 }
323
324 case UNLOAD_ALL_PROVIDERS:
325 {
326 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
327 "_provider_ctrl::UNLOAD_ALL_PROVIDERS");
328 CMPILocalProviderManager *myself = reinterpret_cast<CMPILocalProviderManager *>(parm);
329 CMPIProvider * provider;
330 schuur 1.1 ProviderTable::Iterator i = myself->_providers.start();
331 try
332 {
333 for(; i != 0; i++)
334 {
335 provider = i.value();
336 if(provider == 0)
337 {
338 continue;
339 }
340
341 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
342 "Terminating CMPIProvider " + provider->getName());
343 try
344 {
345 provider->terminate();
346 }
347 catch(...)
348 {
349 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
350 "Exception terminating " +
351 schuur 1.1 provider->getName());
352 continue;
353 }
354 if((provider->_module != 0 ) &&
355 provider->_module->_ref_count.value() == 0)
356 {
357
358 if(true == _modules.lookup(provider->_module->_fileName, provider->_module))
359 {
360 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
361 "Removing CMPIProvider's Module " + provider->getName());
362 _modules.remove(provider->_module->_fileName);
363 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
364 "Destroying CMPIProvider's Module " + provider->getName());
365 delete provider->_module;
366 }
367 }
368 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
369 "Destroying CMPIProvider's CIMOM Handle: " + provider->getName());
370 delete provider->_cimom_handle;
371 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
372 schuur 1.1 "Destroying CMPIProvider: " + provider->getName());
373
374 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
375 "ProviderManager::_provider_crtl - Unload provider $0",
376 provider->getName());
377
378 delete provider;
379 }
380 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
381 "Clearing CMPIProvider Cache" );
382 myself->_providers.clear();
383 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
384 "Clearing Module Cache");
385 myself->_modules.clear();
386 }
387 catch(...)
388 {
389 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
390 "Unexpected Exception in UNLOAD_ALL_PROVIDERS.");
391 }
392 break;
393 schuur 1.1 }
394
395 case UNLOAD_IDLE_PROVIDERS:
396 {
397 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
398 "_provider_ctrl::UNLOAD_IDLE_PROVIDERS");
399
400 quantum++;
401 CMPILocalProviderManager *myself = reinterpret_cast<CMPILocalProviderManager *>(parm);
402 CMPIProvider * provider;
403 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, "providers loaded: " + myself->_providers.size());
404
405 if(myself->_providers.size())
406 {
407 try
408 {
409 struct timeval now;
410 gettimeofday(&now, NULL);
411 ProviderTable::Iterator i = myself->_providers.start();
412 for(; i != 0 ; i++)
413 {
414 schuur 1.1 provider = i.value();
415 if(provider == 0)
416 {
417 myself->_providers.remove(i.key());
418 i = myself->_providers.start();
419 continue;
420 }
421
422 if(provider->_quantum == quantum)
423 {
424 continue;
425 }
426
427 provider->_quantum = quantum;
428
429 if(provider->_current_operations.value())
430 {
431 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
432 "CMPIProvider has pending operations: " +
433 provider->getName());
434 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
435 schuur 1.1 "CMPIProvider has pending operations" + provider->getName() );
436
437 continue;
438 }
439
440 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
441 "Checking timeout data for CMPIProvider: " +
442 provider->getName());
443 struct timeval timeout = {0,0};
444 provider->get_idle_timer(&timeout);
445 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
446 " provider->unload_ok() returns: " +
447 provider->unload_ok() ? "true" : "false" );
448
449 if(provider->unload_ok() == true &&
450 ( now.tv_sec - timeout.tv_sec) > ((Sint32)myself->_idle_timeout))
451 {
452
453 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
454 "ProviderManager::_provider_crtl - Unload idle provider $0",
455 provider->getName());
456 schuur 1.1
457 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
458 "Trying to Terminate CMPIProvider " + provider->getName());
459 try
460 {
461 if(false == provider->tryTerminate())
462 {
463 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
464 "CMPIProvider Refused Termination " + provider->getName());
465
466 continue;
467 }
468 else
469 {
470 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
471 "CMPIProvider terminated: " + provider->getName());
472 }
473 }
474 catch(...)
475 {
476 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
477 schuur 1.1 "Exception terminating " +
478 provider->getName());
479 i = myself->_providers.start();
480 continue;
481 }
482
483 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
484 "Removing CMPIProvider " + provider->getName());
485 myself->_providers.remove(provider->_name);
486
487 // Important = reset iterator to beginning of list. quantum value assures we do
488 // not inspect providers more than once even though we traverse them.
489 i = myself->_providers.start();
490 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
491 provider->_name + " Removed, looking at Module" );
492 if(provider->_module != 0)
493 {
494 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
495 "Module ref: " + provider->_module->_ref_count.value() );
496 if(provider->_module->_ref_count.value() == 0)
497 {
498 schuur 1.1 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
499 "Removing Module " + provider->_module->_fileName);
500 _modules.remove(provider->_module->_fileName);
501 delete provider->_module;
502
503 }
504 }
505
506 try
507 {
508 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
509 "Destroying CMPIProvider's CIMOM Handle: " +
510 provider->getName());
511 delete provider->_cimom_handle;
512 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
513 "Destroying CMPIProvider: " +
514 provider->getName());
515 delete provider;
516 }
517 catch(...)
518 {
519 schuur 1.1 // we may leak if any of the destructors
520 // throws an exception
521 }
522 }
523 }
524 }
525 catch(...)
526 {
527 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
528 "Unexpected Exception in UNLOAD_IDLE_PROVIDERS.");
529 }
530 } // if there are any providers
531 break;
532 }
533
534 case UNLOAD_IDLE_MODULES:
535 {
536
537 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
538 "_provider_ctrl::UNLOAD_IDLE_MODULES");
539
540 schuur 1.1 CMPILocalProviderManager *myself = reinterpret_cast<CMPILocalProviderManager *>(parm);
541 CMPIProviderModule *module;
542 ModuleTable::Iterator i = myself->_modules.start();
543 for(; i ; i++)
544 {
545 module = i.value();
546 if(module->_ref_count.value() == 0)
547 {
548 myself->_modules.remove(module->_fileName);
549 module->unloadModule();
550 delete module;
551 i = myself->_modules.start();
552 }
553 }
554 break;
555 }
556
557 default:
558 ccode = -1;
559 break;
560 }
561 schuur 1.1 PEG_METHOD_EXIT();
562 return(ccode);
563 }
564
565 CMPIProvider * CMPILocalProviderManager::_getResolver
566 (const String & fileName, const String & interfaceType)
567 {
568 CMPIProvider *pr;
569 String id(interfaceType+String("::")+fileName);
570 if (true == _resolvers.lookup(id,pr)) {
571 return pr;
572 }
573 return NULL;
574 }
575
576 CMPIResolverModule *CMPILocalProviderManager::_loadResolver
577 (const String & fileName)
578 {
579 CMPIResolverModule *rm=new CMPIResolverModule(fileName);
580 rm->load();
581 return rm;
582 schuur 1.1 }
583
584 CMPIProvider::OpProviderHolder CMPILocalProviderManager::getProvider(
585 const String & fileName,
586 const String & providerName,
587 const String & interfaceName)
588 {
589 CMPIProvider::OpProviderHolder ph;
590 CTRL_STRINGS strings;
591 Sint32 ccode;
592 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "ProviderManager::getProvider");
593 strings.fileName = &fileName;
594 strings.providerName = &providerName;
595 strings.interfaceName = &interfaceName;
596
597 try {
598 ccode = _provider_ctrl( GET_PROVIDER, &strings, &ph );
599 }
600 catch (Exception e) {
601 std::cerr<<"--- loading proxy: "<<e.getMessage()<<std::endl;
602 PEG_METHOD_EXIT();
603 schuur 1.1 throw;
604 }
605 catch(...) {
606 PEG_METHOD_EXIT();
607 throw;
608 }
609
610
611 PEG_METHOD_EXIT();
612 return(ph);
613
614 }
615
616 void CMPILocalProviderManager::unloadProvider(
617 const String & fileName,
618 const String & providerName)
619 {
620 CTRL_STRINGS strings;
621 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "ProviderManager::unloadProvider");
622 strings.fileName = &fileName;
623 strings.providerName = &providerName;
624 schuur 1.1 _provider_ctrl(UNLOAD_PROVIDER, &strings, (void *)0);
625 PEG_METHOD_EXIT();
626 }
627
628 void CMPILocalProviderManager::shutdownAllProviders(void)
629 {
630
631 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "ProviderManager::shutdownAllProviders");
632 _provider_ctrl(UNLOAD_ALL_PROVIDERS, (void *)this, (void *)0);
633 PEG_METHOD_EXIT();
634 }
635
636
637 // << Tue Jul 29 16:51:25 2003 mdd >> change to run every 300 seconds
638 void CMPILocalProviderManager::unload_idle_providers(void)
639 {
640 static struct timeval first = {0,0}, now, last = {0,0};
641 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "ProviderManager::unload_idle_providers");
642
643 if(first.tv_sec == 0)
644 gettimeofday(&first, NULL);
645 schuur 1.1 gettimeofday(&now, NULL);
646 if(((now.tv_sec - first.tv_sec) > 300 ) && ( (now.tv_sec - last.tv_sec) > 300))
647 {
648 gettimeofday(&last, NULL);
649 if(_unload_idle_flag.value() == 1)
650 {
651 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
652 "Unload Idle Flag Set: Starting CMPIProvider Monitor Thread");
653 _unload_idle_flag = 0;
654 MessageQueueService::get_thread_pool()->allocate_and_awaken(this, provider_monitor);
655
656 }
657 }
658 PEG_METHOD_EXIT();
659 }
660
661
662 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL CMPILocalProviderManager::provider_monitor(void *parm)
663 {
664 Thread *th = reinterpret_cast<Thread *>(parm);
665
666 schuur 1.1 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "ProviderManager::provider_monitor");
667 CMPILocalProviderManager *myself = my_instance ;
668
669 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
670 "Checking for Idle providers to unload.");
671 try
672 {
673 myself->_provider_ctrl(UNLOAD_IDLE_PROVIDERS, myself, (void *)0);
674 myself->_unload_idle_flag = 1;
675 }
676 catch(...)
677 {
678 }
679 PEG_METHOD_EXIT();
680 return(0);
681 }
682
683 PEGASUS_NAMESPACE_END
684
|