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