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