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.18 : _providerManagerRouter(_indicationCallback),
92 _threadPool(0, "ProviderAgent", 0, 0, deallocateWait)
|
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 kumpf 1.17 // Notify the cimserver that the provider agent is exiting cleanly.
185 Uint32 messageLength = 0;
186 _pipeToServer->writeBuffer((const char*)&messageLength, sizeof(Uint32));
187
|
188 kumpf 1.1 PEG_METHOD_EXIT();
189 }
190
191 Boolean ProviderAgent::_readAndProcessRequest()
192 {
193 PEG_METHOD_ENTER(TRC_PROVIDERAGENT,
194 "ProviderAgent::_readAndProcessRequest");
195
196 CIMRequestMessage* request;
197
198 //
199 // Read the request from CIM Server
200 //
201 CIMMessage* cimMessage;
202 AnonymousPipe::Status readStatus = _pipeFromServer->readMessage(cimMessage);
203 request = dynamic_cast<CIMRequestMessage*>(cimMessage);
204
205 // Read operation was interrupted
206 if (readStatus == AnonymousPipe::STATUS_INTERRUPT)
207 {
208 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
209 kumpf 1.1 "Read operation was interrupted.");
210 PEG_METHOD_EXIT();
211 return false;
212 }
213
214 if (readStatus == AnonymousPipe::STATUS_CLOSED)
215 {
216 // The CIM Server connection is closed
217 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
218 "CIMServer connection closed. Exiting.");
219 _terminating = true;
220 PEG_METHOD_EXIT();
221 return false;
222 }
223
224 if (readStatus == AnonymousPipe::STATUS_ERROR)
225 {
226 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
227 "Error reading from pipe. Exiting.");
228 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
229 "ProviderManager.ProviderAgent.ProviderAgent."
230 kumpf 1.1 "CIMSERVER_COMMUNICATION_FAILED",
231 "cimprovagt \"$0\" communication with CIM Server failed. Exiting.",
232 _agentId);
233 _terminating = true;
234 PEG_METHOD_EXIT();
235 return false;
236 }
237
238 // A "wake up" message means we should unload idle providers
239 if (request == 0)
240 {
241 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL4,
242 "Got a wake up message.");
243 try
244 {
245 _unloadIdleProviders();
246 }
247 catch (...)
248 {
249 // Ignore exceptions from idle provider unloading
250 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
251 kumpf 1.1 "Ignoring exception from _unloadIdleProviders()");
252 }
253 PEG_METHOD_EXIT();
254 return false;
255 }
256
257 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL3,
258 String("Received request from server with messageId ") +
259 request->messageId);
260
|
261 kumpf 1.2 // Get the ProviderIdContainer to complete the provider module instance
262 // optimization. If the provider module instance is blank (optimized
263 // out), fill it in from our cache. If it is not blank, update our
264 // cache. (See the _providerModuleCache member description.)
265 try
266 {
267 ProviderIdContainer pidc = request->operationContext.get(
268 ProviderIdContainer::NAME);
269 if (pidc.getModule().isUninitialized())
270 {
271 // Provider module is optimized out. Fill it in from the cache.
272 request->operationContext.set(ProviderIdContainer(
273 _providerModuleCache, pidc.getProvider(),
274 pidc.isRemoteNameSpace(), pidc.getRemoteInfo()));
275 }
276 else
277 {
278 // Update the cache with the new provider module instance.
279 _providerModuleCache = pidc.getModule();
280 }
281 }
282 kumpf 1.2 catch (...)
283 {
284 // No ProviderIdContainer to optimize
285 }
286
|
287 kumpf 1.1 //
288 // Check for messages to be handled by the Agent itself.
289 //
290 if (request->getType() == CIM_INITIALIZE_PROVIDER_AGENT_REQUEST_MESSAGE)
291 {
292 // Process the request in this thread
|
293 kumpf 1.3 AutoPtr<CIMInitializeProviderAgentRequestMessage> ipaRequest(
294 dynamic_cast<CIMInitializeProviderAgentRequestMessage*>(request));
295 PEGASUS_ASSERT(ipaRequest.get() != 0);
|
296 kumpf 1.1
297 ConfigManager* configManager = ConfigManager::getInstance();
298 configManager->setPegasusHome(ipaRequest->pegasusHome);
299
300 // Initialize the configuration properties
301 for (Uint32 i = 0; i < ipaRequest->configProperties.size(); i++)
302 {
303 configManager->initCurrentValue(
304 ipaRequest->configProperties[i].first,
305 ipaRequest->configProperties[i].second);
306 }
307
308 // Set the default resource bundle directory for the MessageLoader
309 MessageLoader::setPegasusMsgHome(ConfigManager::getHomedPath(
310 configManager->getCurrentValue("messageDir")));
311
312 // Set the log file directory
|
313 konrad.r 1.11 #if !defined(PEGASUS_USE_SYSLOGS)
|
314 kumpf 1.1 Logger::setHomeDirectory(ConfigManager::getHomedPath(
315 configManager->getCurrentValue("logdir")));
|
316 konrad.r 1.11 #endif
|
317 kumpf 1.1 System::bindVerbose = ipaRequest->bindVerbose;
318
|
319 carolann.graves 1.8 //
320 // Set _subscriptionInitComplete from value in
321 // InitializeProviderAgent request
322 //
323 _subscriptionInitComplete = ipaRequest->subscriptionInitComplete;
324 _providerManagerRouter.setSubscriptionInitComplete
325 (_subscriptionInitComplete);
326
|
327 kumpf 1.1 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
328 "Processed the agent initialization message.");
329
330 // Do not write a response for this request
331 }
332 else if (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE)
333 {
334 // Process the request in this thread
|
335 kumpf 1.3 AutoPtr<CIMNotifyConfigChangeRequestMessage> notifyRequest(
336 dynamic_cast<CIMNotifyConfigChangeRequestMessage*>(request));
337 PEGASUS_ASSERT(notifyRequest.get() != 0);
|
338 kumpf 1.1
339 //
340 // Update the ConfigManager with the new property value
341 //
342 ConfigManager* configManager = ConfigManager::getInstance();
343 CIMException responseException;
344 try
345 {
346 if (notifyRequest->currentValueModified)
347 {
348 configManager->updateCurrentValue(
349 notifyRequest->propertyName,
350 notifyRequest->newPropertyValue,
351 false);
352 }
353 else
354 {
355 configManager->updatePlannedValue(
356 notifyRequest->propertyName,
357 notifyRequest->newPropertyValue,
358 true);
359 kumpf 1.1 }
360 }
361 catch (Exception& e)
362 {
363 responseException = PEGASUS_CIM_EXCEPTION(
364 CIM_ERR_FAILED, e.getMessage());
365 }
366
|
367 kumpf 1.3 AutoPtr<CIMResponseMessage> response(notifyRequest->buildResponse());
|
368 kumpf 1.1 response->cimException = responseException;
369
370 // Return response to CIM Server
|
371 kumpf 1.3 _writeResponse(response.get());
|
372 kumpf 1.1 }
373 else if ((request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE) ||
374 (request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE))
375 {
376 // Process the request in this thread
|
377 kumpf 1.3 AutoPtr<Message> response(_processRequest(request));
378 _writeResponse(response.get());
|
379 kumpf 1.1
380 CIMResponseMessage * respMsg =
|
381 kumpf 1.3 dynamic_cast<CIMResponseMessage*>(response.get());
|
382 kumpf 1.1
383 // If StopAllProviders, terminate the agent process.
384 // If DisableModule not successful, leave agent process running.
385 if ((respMsg->cimException.getCode() == CIM_ERR_SUCCESS) ||
386 (request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE))
387 {
388 // Operation is successful. End the agent process.
389 _terminating = true;
390 }
|
391 kumpf 1.3
392 delete request;
|
393 kumpf 1.1 }
|
394 carolann.graves 1.8 else if (request->getType () ==
395 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE)
396 {
397 _subscriptionInitComplete = true;
398
399 //
400 // Process the request in this thread
401 //
402 AutoPtr <Message> response (_processRequest (request));
403 _writeResponse (response.get ());
404
405 //
406 // Note: the response does not contain interesting data
407 //
408
409 delete request;
410 }
|
411 kumpf 1.1 else
412 {
413 // Start a new thread to process the request
414 ProviderAgentRequest* agentRequest =
415 new ProviderAgentRequest(this, request);
|
416 kumpf 1.14 ThreadStatus rtn = PEGASUS_THREAD_OK;
|
417 kumpf 1.1
|
418 kumpf 1.14 while ((rtn = _threadPool.allocate_and_awaken(agentRequest,
419 ProviderAgent::_processRequestAndWriteResponse)) !=
420 PEGASUS_THREAD_OK)
421 {
422 if (rtn == PEGASUS_THREAD_INSUFFICIENT_RESOURCES)
423 {
424 pegasus_yield();
425 }
426 else
427 {
428 Logger::put(
429 Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
430 "Not enough threads to process agent request.");
|
431 konrad.r 1.13
|
432 kumpf 1.14 Tracer::trace(TRC_PROVIDERAGENT, Tracer::LEVEL2,
433 "Could not allocate thread to process agent request.");
434
435 AutoPtr<CIMResponseMessage> response(request->buildResponse());
436 response->cimException = PEGASUS_CIM_EXCEPTION_L(
437 CIM_ERR_FAILED,
438 MessageLoaderParms(
439 "ProviderManager.ProviderAgent.ProviderAgent."
440 "THREAD_ALLOCATION_FAILED",
441 "Failed to allocate a thread in cimprovagt \"$0\".",
442 _agentId));
443
444 // Return response to CIM Server
445 _writeResponse(response.get());
446
447 delete agentRequest;
448 delete request;
449
450 break;
451 }
452 }
|
453 kumpf 1.1 }
454
455 PEG_METHOD_EXIT();
456 return true;
457 }
458
459 Message* ProviderAgent::_processRequest(CIMRequestMessage* request)
460 {
461 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_processRequest");
462
463 Message* response = 0;
464
465 try
466 {
467 // Forward the request to the ProviderManager
468 response = _providerManagerRouter.processMessage(request);
469 }
470 catch (Exception& e)
471 {
472 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
473 String("Caught exception while processing request: ") +
474 kumpf 1.1 e.getMessage());
475 CIMResponseMessage* cimResponse = request->buildResponse();
476 cimResponse->cimException = PEGASUS_CIM_EXCEPTION(
477 CIM_ERR_FAILED, e.getMessage());
478 response = cimResponse;
479 }
480 catch (...)
481 {
482 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
483 "Caught exception while processing request.");
484 CIMResponseMessage* cimResponse = request->buildResponse();
485 cimResponse->cimException = PEGASUS_CIM_EXCEPTION(
486 CIM_ERR_FAILED, String::EMPTY);
487 response = cimResponse;
488 }
489
490 PEG_METHOD_EXIT();
491 return response;
492 }
493
494 void ProviderAgent::_writeResponse(Message* message)
495 kumpf 1.1 {
496 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_writeResponse");
497
498 CIMMessage* response = dynamic_cast<CIMMessage*>(message);
499 PEGASUS_ASSERT(response != 0);
500
501 //
502 // Write the response message to the pipe
503 //
504 try
505 {
506 // Use Mutex to prevent concurrent writes to the same pipe
507 AutoMutex pipeLock(_pipeToServerMutex);
508
509 AnonymousPipe::Status writeStatus =
510 _pipeToServer->writeMessage(response);
511
512 if (writeStatus != AnonymousPipe::STATUS_SUCCESS)
513 {
514 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
515 "Error writing response to pipe.");
516 kumpf 1.1 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
517 "ProviderManager.ProviderAgent.ProviderAgent."
518 "CIMSERVER_COMMUNICATION_FAILED",
519 "cimprovagt \"$0\" communication with CIM Server failed. "
520 "Exiting.",
521 _agentId);
522 _terminating = true;
523 }
524 }
525 catch (...)
526 {
527 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
528 "Caught exception while writing response.");
529 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
530 "ProviderManager.ProviderAgent.ProviderAgent."
531 "CIMSERVER_COMMUNICATION_FAILED",
532 "cimprovagt \"$0\" communication with CIM Server failed. Exiting.",
533 _agentId);
534 _terminating = true;
535 }
536
537 kumpf 1.1 PEG_METHOD_EXIT();
538 }
539
540 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL
541 ProviderAgent::_processRequestAndWriteResponse(void* arg)
542 {
543 PEG_METHOD_ENTER(TRC_PROVIDERAGENT,
544 "ProviderAgent::_processRequestAndWriteResponse");
545
546 AutoPtr<ProviderAgentRequest> agentRequest(
547 reinterpret_cast<ProviderAgentRequest*>(arg));
548 PEGASUS_ASSERT(agentRequest.get() != 0);
549
|
550 kumpf 1.12 try
551 {
552 // Get the ProviderAgent and request message from the argument
553 ProviderAgent* agent = agentRequest->agent;
554 AutoPtr<CIMRequestMessage> request(agentRequest->request);
|
555 kumpf 1.1
|
556 kumpf 1.12 // Process the request
557 AutoPtr<Message> response(agent->_processRequest(request.get()));
|
558 kumpf 1.1
|
559 kumpf 1.12 // Write the response
560 agent->_writeResponse(response.get());
561 }
562 catch (const Exception& e)
563 {
564 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
565 "Caught exception: \"" + e.getMessage() +
566 "\". Exiting _processRequestAndWriteResponse.");
567 }
568 catch (...)
569 {
570 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
571 "Caught unrecognized exception. "
572 "Exiting _processRequestAndWriteResponse.");
573 }
|
574 kumpf 1.1
575 PEG_METHOD_EXIT();
576 return(PEGASUS_THREAD_RETURN(0));
577 }
578
579 void ProviderAgent::_indicationCallback(
580 CIMProcessIndicationRequestMessage* message)
581 {
582 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_indicationCallback");
583
584 // Send request back to the server to process
585 _providerAgent->_writeResponse(message);
586
587 PEG_METHOD_EXIT();
588 }
589
590 void ProviderAgent::_unloadIdleProviders()
591 {
592 PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_unloadIdleProviders");
|
593 konrad.r 1.13 ThreadStatus rtn = PEGASUS_THREAD_OK;
|
594 kumpf 1.1 // Ensure that only one _unloadIdleProvidersHandler thread runs at a time
595 _unloadIdleProvidersBusy++;
|
596 mike 1.16 if ((_unloadIdleProvidersBusy.get() == 1) &&
|
597 konrad.r 1.13 ((rtn =_threadPool.allocate_and_awaken(
598 (void*)this, ProviderAgent::_unloadIdleProvidersHandler))==PEGASUS_THREAD_OK))
|
599 kumpf 1.1 {
600 // _unloadIdleProvidersBusy is decremented in
601 // _unloadIdleProvidersHandler
602 }
603 else
604 {
605 // If we fail to allocate a thread, don't retry now.
606 _unloadIdleProvidersBusy--;
607 }
|
608 konrad.r 1.13 if (rtn != PEGASUS_THREAD_OK)
609 {
|
610 kumpf 1.1
|
611 kumpf 1.14 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
612 "Not enough threads to unload idle providers.");
|
613 konrad.r 1.13
|
614 kumpf 1.14 Tracer::trace(TRC_PROVIDERAGENT, Tracer::LEVEL2,
615 "Could not allocate thread to unload idle providers.");
|
616 konrad.r 1.13 }
|
617 kumpf 1.1 PEG_METHOD_EXIT();
618 }
619
620 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL
621 ProviderAgent::_unloadIdleProvidersHandler(void* arg) throw()
622 {
623 try
624 {
625 PEG_METHOD_ENTER(TRC_PROVIDERAGENT,
626 "ProviderAgent::unloadIdleProvidersHandler");
627
628 ProviderAgent* myself = reinterpret_cast<ProviderAgent*>(arg);
629
630 try
631 {
632 myself->_providerManagerRouter.unloadIdleProviders();
633 }
634 catch (...)
635 {
636 // Ignore errors
637 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
638 kumpf 1.1 "Unexpected exception in _unloadIdleProvidersHandler");
639 }
640
641 myself->_unloadIdleProvidersBusy--;
642 }
643 catch (...)
644 {
645 // Ignore errors
646 try
647 {
648 PEG_TRACE_STRING(TRC_PROVIDERAGENT, Tracer::LEVEL2,
649 "Unexpected exception in _unloadIdleProvidersHandler");
650 }
651 catch (...)
652 {
653 }
654 }
655
656 // PEG_METHOD_EXIT(); // Note: This statement could throw an exception
657 return(PEGASUS_THREAD_RETURN(0));
658 }
659 kumpf 1.1
660 void ProviderAgent::_terminateSignalHandler(
661 int s_n, PEGASUS_SIGINFO_T* s_info, void* sig)
662 {
663 PEG_METHOD_ENTER(TRC_PROVIDERAGENT,
664 "ProviderAgent::_terminateSignalHandler");
665
666 if (_providerAgent != 0)
667 {
668 _providerAgent->_terminating = true;
669 }
670
671 PEG_METHOD_EXIT();
672 }
673
674 PEGASUS_NAMESPACE_END
|