1 karl 1.7 //%2005////////////////////////////////////////////////////////////////////////
|
2 kumpf 1.1 //
|
3 karl 1.4 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.7 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 kumpf 1.1 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to
14 // deal in the Software without restriction, including without limitation the
15 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 // sell copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
18 //
19 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
20 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
21 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //==============================================================================
29 //
30 // Author: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
31 // Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
32 kumpf 1.1 //
|
33 carolann.graves 1.8 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
34 // (carolann_graves@hp.com)
|
35 kumpf 1.1 //
36 //%/////////////////////////////////////////////////////////////////////////////
37
38 #include <Pegasus/Common/Array.h>
39 #include <Pegasus/Common/AutoPtr.h>
40 #include <Pegasus/Common/CIMMessageSerializer.h>
41 #include <Pegasus/Common/CIMMessageDeserializer.h>
42 #include <Pegasus/Common/Tracer.h>
43 #include <Pegasus/Config/ConfigManager.h>
44
45 #include "ProviderAgent.h"
46
47 PEGASUS_USING_STD;
48
49 PEGASUS_NAMESPACE_BEGIN
50
51 /////////////////////////////////////////////////////////////////////////////
52 //
53 // ProviderAgentRequest
54 //
55 /////////////////////////////////////////////////////////////////////////////
56 kumpf 1.1
57 /**
58 This class encapsulates the data required by a work thread to process a
59 request in a Provider Agent.
60 */
61 class ProviderAgentRequest
62 {
63 public:
64 ProviderAgentRequest(ProviderAgent* agent_, CIMRequestMessage* request_)
65 {
66 agent = agent_;
67 request = request_;
|
68 a.dunfey 1.6 request->requestIsOOP = true;
|
69 kumpf 1.1 }
70
71 ProviderAgent* agent;
72 CIMRequestMessage* request;
73 };
74
75
76 /////////////////////////////////////////////////////////////////////////////
77 //
78 // ProviderAgent
79 //
80 /////////////////////////////////////////////////////////////////////////////
81
82 // Time values used in ThreadPool construction
|
83 kumpf 1.10 static struct timeval deallocateWait = {300, 0};
|
84 kumpf 1.1
85 ProviderAgent* ProviderAgent::_providerAgent = 0;
86
87 ProviderAgent::ProviderAgent(
88 const String& agentId,
89 AnonymousPipe* pipeFromServer,
90 AnonymousPipe* pipeToServer)
|
91 kumpf 1.10 : _threadPool(0, "ProviderAgent", 0, 0, deallocateWait),
|
92 w.otsuka 1.5 _providerManagerRouter(_indicationCallback)
|
93 kumpf 1.1 {
94 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::ProviderAgent");
95
96 _terminating = false;
97 _agentId = agentId;
98 _pipeFromServer = pipeFromServer;
99 _pipeToServer = pipeToServer;
100 _providerAgent = this;
|
101 carolann.graves 1.8 _subscriptionInitComplete = false;
|
102 kumpf 1.1
103 PEG_METHOD_EXIT();
104 }
105
106 ProviderAgent::~ProviderAgent()
107 {
108 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::~ProviderAgent");
109
110 _providerAgent = 0;
111
112 PEG_METHOD_EXIT();
113 }
114
115 void ProviderAgent::run()
116 {
117 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::run");
118
119 // Enable the signal handler to terminate gracefully on SIGHUP and SIGTERM
120 getSigHandle()->registerHandler(PEGASUS_SIGHUP, _terminateSignalHandler);
121 getSigHandle()->activate(PEGASUS_SIGHUP);
122 getSigHandle()->registerHandler(PEGASUS_SIGTERM, _terminateSignalHandler);
123 kumpf 1.1 getSigHandle()->activate(PEGASUS_SIGTERM);
124
125 while (!_terminating)
126 {
127 Boolean active = true;
128 try
129 {
130 //
131 // Read and process the next request
132 //
133 active = _readAndProcessRequest();
134 }
135 catch (Exception& e)
136 {
137 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
138 String("Unexpected exception from _readAndProcessRequest(): ") +
139 e.getMessage());
140 _terminating = true;
141 }
142 catch (...)
143 {
144 kumpf 1.1 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
145 "Unexpected exception from _readAndProcessRequest().");
146 _terminating = true;
147 }
148
149 if (_terminating)
150 {
151 //
152 // Stop all providers
153 //
154 CIMStopAllProvidersRequestMessage stopRequest("0", QueueIdStack(0));
155 AutoPtr<Message> stopResponse(_processRequest(&stopRequest));
156 }
157 else if (!active)
158 {
159 //
160 // Stop agent process when no more providers are loaded
161 //
162 try
163 {
164 if (!_providerManagerRouter.hasActiveProviders())
165 kumpf 1.1 {
166 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
167 "No active providers. Exiting.");
168 _terminating = true;
169 }
|
170 kumpf 1.15 else
171 {
172 _threadPool.cleanupIdleThreads();
173 }
|
174 kumpf 1.1 }
175 catch (...)
176 {
177 // Do not terminate the agent on this exception
178 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
179 "Unexpected exception from hasActiveProviders()");
180 }
181 }
182 }
183
184 PEG_METHOD_EXIT();
185 }
186
187 Boolean ProviderAgent::_readAndProcessRequest()
188 {
189 PEG_METHOD_ENTER(TRC_PROVIDERAGENT,
190 "ProviderAgent::_readAndProcessRequest");
191
192 CIMRequestMessage* request;
193
194 //
195 kumpf 1.1 // Read the request from CIM Server
196 //
197 CIMMessage* cimMessage;
198 AnonymousPipe::Status readStatus = _pipeFromServer->readMessage(cimMessage);
199 request = dynamic_cast<CIMRequestMessage*>(cimMessage);
200
201 // Read operation was interrupted
202 if (readStatus == AnonymousPipe::STATUS_INTERRUPT)
203 {
204 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
205 "Read operation was interrupted.");
206 PEG_METHOD_EXIT();
207 return false;
208 }
209
210 if (readStatus == AnonymousPipe::STATUS_CLOSED)
211 {
212 // The CIM Server connection is closed
213 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
214 "CIMServer connection closed. Exiting.");
215 _terminating = true;
216 kumpf 1.1 PEG_METHOD_EXIT();
217 return false;
218 }
219
220 if (readStatus == AnonymousPipe::STATUS_ERROR)
221 {
222 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
223 "Error reading from pipe. Exiting.");
224 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
225 "ProviderManager.ProviderAgent.ProviderAgent."
226 "CIMSERVER_COMMUNICATION_FAILED",
227 "cimprovagt \"$0\" communication with CIM Server failed. Exiting.",
228 _agentId);
229 _terminating = true;
230 PEG_METHOD_EXIT();
231 return false;
232 }
233
234 // A "wake up" message means we should unload idle providers
235 if (request == 0)
236 {
237 kumpf 1.1 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL4,
238 "Got a wake up message.");
239 try
240 {
241 _unloadIdleProviders();
242 }
243 catch (...)
244 {
245 // Ignore exceptions from idle provider unloading
246 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
247 "Ignoring exception from _unloadIdleProviders()");
248 }
249 PEG_METHOD_EXIT();
250 return false;
251 }
252
253 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL3,
254 String("Received request from server with messageId ") +
255 request->messageId);
256
|
257 kumpf 1.2 // Get the ProviderIdContainer to complete the provider module instance
258 // optimization. If the provider module instance is blank (optimized
259 // out), fill it in from our cache. If it is not blank, update our
260 // cache. (See the _providerModuleCache member description.)
261 try
262 {
263 ProviderIdContainer pidc = request->operationContext.get(
264 ProviderIdContainer::NAME);
265 if (pidc.getModule().isUninitialized())
266 {
267 // Provider module is optimized out. Fill it in from the cache.
268 request->operationContext.set(ProviderIdContainer(
269 _providerModuleCache, pidc.getProvider(),
270 pidc.isRemoteNameSpace(), pidc.getRemoteInfo()));
271 }
272 else
273 {
274 // Update the cache with the new provider module instance.
275 _providerModuleCache = pidc.getModule();
276 }
277 }
278 kumpf 1.2 catch (...)
279 {
280 // No ProviderIdContainer to optimize
281 }
282
|
283 kumpf 1.1 //
284 // Check for messages to be handled by the Agent itself.
285 //
286 if (request->getType() == CIM_INITIALIZE_PROVIDER_AGENT_REQUEST_MESSAGE)
287 {
288 // Process the request in this thread
|
289 kumpf 1.3 AutoPtr<CIMInitializeProviderAgentRequestMessage> ipaRequest(
290 dynamic_cast<CIMInitializeProviderAgentRequestMessage*>(request));
291 PEGASUS_ASSERT(ipaRequest.get() != 0);
|
292 kumpf 1.1
293 ConfigManager* configManager = ConfigManager::getInstance();
294 configManager->setPegasusHome(ipaRequest->pegasusHome);
295
296 // Initialize the configuration properties
297 for (Uint32 i = 0; i < ipaRequest->configProperties.size(); i++)
298 {
299 configManager->initCurrentValue(
300 ipaRequest->configProperties[i].first,
301 ipaRequest->configProperties[i].second);
302 }
303
304 // Set the default resource bundle directory for the MessageLoader
305 MessageLoader::setPegasusMsgHome(ConfigManager::getHomedPath(
306 configManager->getCurrentValue("messageDir")));
307
308 // Set the log file directory
|
309 konrad.r 1.11 #if !defined(PEGASUS_USE_SYSLOGS)
|
310 kumpf 1.1 Logger::setHomeDirectory(ConfigManager::getHomedPath(
311 configManager->getCurrentValue("logdir")));
|
312 konrad.r 1.11 #endif
|
313 kumpf 1.1 System::bindVerbose = ipaRequest->bindVerbose;
314
|
315 carolann.graves 1.8 //
316 // Set _subscriptionInitComplete from value in
317 // InitializeProviderAgent request
318 //
319 _subscriptionInitComplete = ipaRequest->subscriptionInitComplete;
320 _providerManagerRouter.setSubscriptionInitComplete
321 (_subscriptionInitComplete);
322
|
323 kumpf 1.1 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
324 "Processed the agent initialization message.");
325
326 // Do not write a response for this request
327 }
328 else if (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE)
329 {
330 // Process the request in this thread
|
331 kumpf 1.3 AutoPtr<CIMNotifyConfigChangeRequestMessage> notifyRequest(
332 dynamic_cast<CIMNotifyConfigChangeRequestMessage*>(request));
333 PEGASUS_ASSERT(notifyRequest.get() != 0);
|
334 kumpf 1.1
335 //
336 // Update the ConfigManager with the new property value
337 //
338 ConfigManager* configManager = ConfigManager::getInstance();
339 CIMException responseException;
340 try
341 {
342 if (notifyRequest->currentValueModified)
343 {
344 configManager->updateCurrentValue(
345 notifyRequest->propertyName,
346 notifyRequest->newPropertyValue,
347 false);
348 }
349 else
350 {
351 configManager->updatePlannedValue(
352 notifyRequest->propertyName,
353 notifyRequest->newPropertyValue,
354 true);
355 kumpf 1.1 }
356 }
357 catch (Exception& e)
358 {
359 responseException = PEGASUS_CIM_EXCEPTION(
360 CIM_ERR_FAILED, e.getMessage());
361 }
362
|
363 kumpf 1.3 AutoPtr<CIMResponseMessage> response(notifyRequest->buildResponse());
|
364 kumpf 1.1 response->cimException = responseException;
365
366 // Return response to CIM Server
|
367 kumpf 1.3 _writeResponse(response.get());
|
368 kumpf 1.1 }
369 else if ((request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE) ||
370 (request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE))
371 {
372 // Process the request in this thread
|
373 kumpf 1.3 AutoPtr<Message> response(_processRequest(request));
374 _writeResponse(response.get());
|
375 kumpf 1.1
376 CIMResponseMessage * respMsg =
|
377 kumpf 1.3 dynamic_cast<CIMResponseMessage*>(response.get());
|
378 kumpf 1.1
379 // If StopAllProviders, terminate the agent process.
380 // If DisableModule not successful, leave agent process running.
381 if ((respMsg->cimException.getCode() == CIM_ERR_SUCCESS) ||
382 (request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE))
383 {
384 // Operation is successful. End the agent process.
385 _terminating = true;
386 }
|
387 kumpf 1.3
388 delete request;
|
389 kumpf 1.1 }
|
390 carolann.graves 1.8 else if (request->getType () ==
391 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE)
392 {
393 _subscriptionInitComplete = true;
394
395 //
396 // Process the request in this thread
397 //
398 AutoPtr <Message> response (_processRequest (request));
399 _writeResponse (response.get ());
400
401 //
402 // Note: the response does not contain interesting data
403 //
404
405 delete request;
406 }
|
407 kumpf 1.1 else
408 {
409 // Start a new thread to process the request
410 ProviderAgentRequest* agentRequest =
411 new ProviderAgentRequest(this, request);
|
412 kumpf 1.14 ThreadStatus rtn = PEGASUS_THREAD_OK;
|
413 kumpf 1.1
|
414 kumpf 1.14 while ((rtn = _threadPool.allocate_and_awaken(agentRequest,
415 ProviderAgent::_processRequestAndWriteResponse)) !=
416 PEGASUS_THREAD_OK)
417 {
418 if (rtn == PEGASUS_THREAD_INSUFFICIENT_RESOURCES)
419 {
420 pegasus_yield();
421 }
422 else
423 {
424 Logger::put(
425 Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
426 "Not enough threads to process agent request.");
|
427 konrad.r 1.13
|
428 kumpf 1.14 Tracer::trace(TRC_PROVIDERAGENT, Tracer::LEVEL2,
429 "Could not allocate thread to process agent request.");
430
431 AutoPtr<CIMResponseMessage> response(request->buildResponse());
432 response->cimException = PEGASUS_CIM_EXCEPTION_L(
433 CIM_ERR_FAILED,
434 MessageLoaderParms(
435 "ProviderManager.ProviderAgent.ProviderAgent."
436 "THREAD_ALLOCATION_FAILED",
437 "Failed to allocate a thread in cimprovagt \"$0\".",
438 _agentId));
439
440 // Return response to CIM Server
441 _writeResponse(response.get());
442
443 delete agentRequest;
444 delete request;
445
446 break;
447 }
448 }
|
449 kumpf 1.1 }
450
451 PEG_METHOD_EXIT();
452 return true;
453 }
454
455 Message* ProviderAgent::_processRequest(CIMRequestMessage* request)
456 {
457 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_processRequest");
458
459 Message* response = 0;
460
461 try
462 {
463 // Forward the request to the ProviderManager
464 response = _providerManagerRouter.processMessage(request);
465 }
466 catch (Exception& e)
467 {
468 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
469 String("Caught exception while processing request: ") +
470 kumpf 1.1 e.getMessage());
471 CIMResponseMessage* cimResponse = request->buildResponse();
472 cimResponse->cimException = PEGASUS_CIM_EXCEPTION(
473 CIM_ERR_FAILED, e.getMessage());
474 response = cimResponse;
475 }
476 catch (...)
477 {
478 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
479 "Caught exception while processing request.");
480 CIMResponseMessage* cimResponse = request->buildResponse();
481 cimResponse->cimException = PEGASUS_CIM_EXCEPTION(
482 CIM_ERR_FAILED, String::EMPTY);
483 response = cimResponse;
484 }
485
486 PEG_METHOD_EXIT();
487 return response;
488 }
489
490 void ProviderAgent::_writeResponse(Message* message)
491 kumpf 1.1 {
492 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_writeResponse");
493
494 CIMMessage* response = dynamic_cast<CIMMessage*>(message);
495 PEGASUS_ASSERT(response != 0);
496
497 //
498 // Write the response message to the pipe
499 //
500 try
501 {
502 // Use Mutex to prevent concurrent writes to the same pipe
503 AutoMutex pipeLock(_pipeToServerMutex);
504
505 AnonymousPipe::Status writeStatus =
506 _pipeToServer->writeMessage(response);
507
508 if (writeStatus != AnonymousPipe::STATUS_SUCCESS)
509 {
510 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
511 "Error writing response to pipe.");
512 kumpf 1.1 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
513 "ProviderManager.ProviderAgent.ProviderAgent."
514 "CIMSERVER_COMMUNICATION_FAILED",
515 "cimprovagt \"$0\" communication with CIM Server failed. "
516 "Exiting.",
517 _agentId);
518 _terminating = true;
519 }
520 }
521 catch (...)
522 {
523 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
524 "Caught exception while writing response.");
525 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
526 "ProviderManager.ProviderAgent.ProviderAgent."
527 "CIMSERVER_COMMUNICATION_FAILED",
528 "cimprovagt \"$0\" communication with CIM Server failed. Exiting.",
529 _agentId);
530 _terminating = true;
531 }
532
533 kumpf 1.1 PEG_METHOD_EXIT();
534 }
535
536 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL
537 ProviderAgent::_processRequestAndWriteResponse(void* arg)
538 {
539 PEG_METHOD_ENTER(TRC_PROVIDERAGENT,
540 "ProviderAgent::_processRequestAndWriteResponse");
541
542 AutoPtr<ProviderAgentRequest> agentRequest(
543 reinterpret_cast<ProviderAgentRequest*>(arg));
544 PEGASUS_ASSERT(agentRequest.get() != 0);
545
|
546 kumpf 1.12 try
547 {
548 // Get the ProviderAgent and request message from the argument
549 ProviderAgent* agent = agentRequest->agent;
550 AutoPtr<CIMRequestMessage> request(agentRequest->request);
|
551 kumpf 1.1
|
552 kumpf 1.12 // Process the request
553 AutoPtr<Message> response(agent->_processRequest(request.get()));
|
554 kumpf 1.1
|
555 kumpf 1.12 // Write the response
556 agent->_writeResponse(response.get());
557 }
558 catch (const Exception& e)
559 {
560 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
561 "Caught exception: \"" + e.getMessage() +
562 "\". Exiting _processRequestAndWriteResponse.");
563 }
564 catch (...)
565 {
566 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
567 "Caught unrecognized exception. "
568 "Exiting _processRequestAndWriteResponse.");
569 }
|
570 kumpf 1.1
571 PEG_METHOD_EXIT();
572 return(PEGASUS_THREAD_RETURN(0));
573 }
574
575 void ProviderAgent::_indicationCallback(
576 CIMProcessIndicationRequestMessage* message)
577 {
578 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_indicationCallback");
579
580 // Send request back to the server to process
581 _providerAgent->_writeResponse(message);
582
583 PEG_METHOD_EXIT();
584 }
585
586 void ProviderAgent::_unloadIdleProviders()
587 {
588 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_unloadIdleProviders");
|
589 konrad.r 1.13 ThreadStatus rtn = PEGASUS_THREAD_OK;
|
590 kumpf 1.1 // Ensure that only one _unloadIdleProvidersHandler thread runs at a time
591 _unloadIdleProvidersBusy++;
592 if ((_unloadIdleProvidersBusy.value() == 1) &&
|
593 konrad.r 1.13 ((rtn =_threadPool.allocate_and_awaken(
594 (void*)this, ProviderAgent::_unloadIdleProvidersHandler))==PEGASUS_THREAD_OK))
|
595 kumpf 1.1 {
596 // _unloadIdleProvidersBusy is decremented in
597 // _unloadIdleProvidersHandler
598 }
599 else
600 {
601 // If we fail to allocate a thread, don't retry now.
602 _unloadIdleProvidersBusy--;
603 }
|
604 konrad.r 1.13 if (rtn != PEGASUS_THREAD_OK)
605 {
|
606 kumpf 1.1
|
607 kumpf 1.14 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
608 "Not enough threads to unload idle providers.");
|
609 konrad.r 1.13
|
610 kumpf 1.14 Tracer::trace(TRC_PROVIDERAGENT, Tracer::LEVEL2,
611 "Could not allocate thread to unload idle providers.");
|
612 konrad.r 1.13 }
|
613 kumpf 1.1 PEG_METHOD_EXIT();
614 }
615
616 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL
617 ProviderAgent::_unloadIdleProvidersHandler(void* arg) throw()
618 {
619 try
620 {
621 PEG_METHOD_ENTER(TRC_PROVIDERAGENT,
622 "ProviderAgent::unloadIdleProvidersHandler");
623
624 ProviderAgent* myself = reinterpret_cast<ProviderAgent*>(arg);
625
626 try
627 {
628 myself->_providerManagerRouter.unloadIdleProviders();
629 }
630 catch (...)
631 {
632 // Ignore errors
633 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
634 kumpf 1.1 "Unexpected exception in _unloadIdleProvidersHandler");
635 }
636
637 myself->_unloadIdleProvidersBusy--;
638 }
639 catch (...)
640 {
641 // Ignore errors
642 try
643 {
644 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
645 "Unexpected exception in _unloadIdleProvidersHandler");
646 }
647 catch (...)
648 {
649 }
650 }
651
652 // PEG_METHOD_EXIT(); // Note: This statement could throw an exception
653 return(PEGASUS_THREAD_RETURN(0));
654 }
655 kumpf 1.1
656 void ProviderAgent::_terminateSignalHandler(
657 int s_n, PEGASUS_SIGINFO_T* s_info, void* sig)
658 {
659 PEG_METHOD_ENTER(TRC_PROVIDERAGENT,
660 "ProviderAgent::_terminateSignalHandler");
661
662 if (_providerAgent != 0)
663 {
664 _providerAgent->_terminating = true;
665 }
666
667 PEG_METHOD_EXIT();
668 }
669
670 PEGASUS_NAMESPACE_END
|