1 karl 1.40 //%2006////////////////////////////////////////////////////////////////////////
|
2 kumpf 1.1 //
|
3 karl 1.25 // 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 karl 1.12 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.25 // 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.28 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.40 // 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 karl 1.49 //
|
21 kumpf 1.1 // 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 //%/////////////////////////////////////////////////////////////////////////////
33
|
34 tony 1.8 #include "CIMListener.h"
35 #include <Pegasus/Common/Exception.h>
36 #include <Pegasus/Common/SSLContext.h>
37 #include <Pegasus/Common/Monitor.h>
|
38 kumpf 1.1 #include <Pegasus/Common/HTTPAcceptor.h>
|
39 kumpf 1.11 #include <Pegasus/Common/PegasusVersion.h>
|
40 konrad.r 1.38 #include <Pegasus/Common/MessageLoader.h>
|
41 kumpf 1.44 #include <Pegasus/Common/Time.h>
|
42 kumpf 1.1 #include <Pegasus/ExportServer/CIMExportResponseEncoder.h>
43 #include <Pegasus/ExportServer/CIMExportRequestDecoder.h>
|
44 tony 1.8 #include <Pegasus/Consumer/CIMIndicationConsumer.h>
45 #include <Pegasus/Listener/CIMListenerIndicationDispatcher.h>
46
47 PEGASUS_NAMESPACE_BEGIN
|
48 mike 1.41
49 ////////////////////////////////////////////////////////////////////////////////
50 //
|
51 tony 1.8 // CIMListenerService
|
52 mike 1.41 //
53 ////////////////////////////////////////////////////////////////////////////////
54
|
55 tony 1.8 class CIMListenerService
56 {
57 public:
|
58 mike 1.41 CIMListenerService(Uint32 portNumber, SSLContext * sslContext = NULL);
59 CIMListenerService(CIMListenerService & svc);
60 ~CIMListenerService();
61
62 void init();
63
64 /** bind to the port
65 */
66 void bind();
67
68 /** runForever Main runloop for the server.
69 */
70 void runForever();
71
72 /** Call to gracefully shutdown the server. The server connection socket
73 will be closed to disable new connections from clients.
74 */
75 void stopClientConnection();
76
77 /** Call to gracefully shutdown the server. It is called when the server
78 has been stopped and is ready to be shutdown. Next time runForever()
79 mike 1.41 is called, the server shuts down.
80 */
81 void shutdown();
82
83 /** Return true if the server has shutdown, false otherwise.
84 */
85 Boolean terminated() const
86 {
87 return _dieNow;
88 };
|
89 david.dillard 1.34
|
90 mike 1.41 /** Call to resume the sever.
91 */
92 void resume();
93
94 /** Call to set the CIMServer state. Also inform the appropriate
95 message queues about the current state of the CIMServer.
96 */
97 void setState(Uint32 state);
98
99 Uint32 getOutstandingRequestCount();
100
101 /** Returns the indication listener dispatcher
102 */
103 CIMListenerIndicationDispatcher *getIndicationDispatcher() const;
104
105 /** Returns the indication listener dispatcher
106 */
107 void setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher);
108
109 /** Returns the port number being used.
110 */
111 mike 1.41 Uint32 getPortNumber() const;
112
|
113 karl 1.49 static ThreadReturnType PEGASUS_THREAD_CDECL
|
114 mike 1.41 _listener_routine(void *param);
|
115 tony 1.8
116 private:
|
117 mike 1.41 Uint32 _portNumber;
118 SSLContext *_sslContext;
119 Monitor *_monitor;
120 Mutex _monitorMutex;
|
121 dave.sudlik 1.48 HTTPAcceptor *_ip6Acceptor;
122 HTTPAcceptor *_ip4Acceptor;
|
123 mike 1.41 Boolean _dieNow;
124 CIMListenerIndicationDispatcher *_dispatcher;
125 CIMExportResponseEncoder *_responseEncoder;
126 CIMExportRequestDecoder *_requestDecoder;
|
127 tony 1.8 };
128
|
129 mike 1.41 CIMListenerService::CIMListenerService(
|
130 karl 1.49 Uint32 portNumber,
|
131 mike 1.41 SSLContext * sslContext)
132 :
|
133 karl 1.49 _portNumber(portNumber),
134 _sslContext(sslContext),
|
135 mike 1.41 _monitor(NULL),
|
136 dave.sudlik 1.48 _ip6Acceptor(NULL),
137 _ip4Acceptor(NULL),
|
138 karl 1.49 _dieNow(false),
139 _dispatcher(NULL),
|
140 mike 1.41 _responseEncoder(NULL),
141 _requestDecoder(NULL)
|
142 tony 1.8 {
143 }
144
|
145 mike 1.41 CIMListenerService::CIMListenerService(CIMListenerService & svc) :
|
146 karl 1.49 _portNumber(svc._portNumber),
147 _sslContext(svc._sslContext),
|
148 mike 1.41 _monitor(NULL),
|
149 dave.sudlik 1.48 _ip6Acceptor(NULL),
150 _ip4Acceptor(NULL),
|
151 karl 1.49 _dieNow(svc._dieNow),
|
152 mike 1.41 _dispatcher(NULL),
|
153 karl 1.49 _responseEncoder(NULL),
|
154 mike 1.41 _requestDecoder(NULL)
|
155 tony 1.8 {
156 }
|
157 mike 1.41
|
158 tony 1.8 CIMListenerService::~CIMListenerService()
159 {
|
160 kumpf 1.36 delete _responseEncoder;
161 delete _requestDecoder;
|
162 dave.sudlik 1.48 delete _ip6Acceptor;
163 delete _ip4Acceptor;
|
164 kumpf 1.36 delete _monitor;
|
165 tony 1.8 }
|
166 kumpf 1.1
|
167 tony 1.8 void CIMListenerService::init()
|
168 kumpf 1.1 {
|
169 mike 1.41 PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::init");
|
170 kumpf 1.1
|
171 mike 1.41 if (NULL == _monitor)
172 _monitor = new Monitor();
|
173 david.dillard 1.31
|
174 mike 1.41 // _dispatcher = new CIMListenerIndicationDispatcher();
|
175 kumpf 1.1
|
176 mike 1.41 if (NULL == _responseEncoder)
177 _responseEncoder = new CIMExportResponseEncoder();
|
178 tony 1.8
|
179 mike 1.41 if (NULL == _requestDecoder)
180 {
181 _requestDecoder = new CIMExportRequestDecoder(
182 _dispatcher, _responseEncoder->getQueueId());
183 }
|
184 dave.sudlik 1.48 #ifdef PEGASUS_ENABLE_IPV6
|
185 venkat.puvvada 1.50 if (System::isIPv6StackActive())
|
186 dave.sudlik 1.48 {
|
187 venkat.puvvada 1.50 if (NULL == _ip6Acceptor)
188 {
189 _ip6Acceptor = new HTTPAcceptor(
190 _monitor, _requestDecoder, HTTPAcceptor::IPV6_CONNECTION,
191 _portNumber, _sslContext, false);
192 }
|
193 dave.sudlik 1.48 }
|
194 venkat.puvvada 1.50 #ifndef PEGASUS_OS_TYPE_WINDOWS
195 else
196 #endif
|
197 dave.sudlik 1.48 #endif
198 if (NULL == _ip4Acceptor)
|
199 mike 1.41 {
|
200 dave.sudlik 1.48 _ip4Acceptor = new HTTPAcceptor(
201 _monitor, _requestDecoder, HTTPAcceptor::IPV4_CONNECTION,
202 _portNumber, _sslContext, false);
|
203 mike 1.41 }
204 bind();
205
206 PEG_METHOD_EXIT();
|
207 tony 1.8 }
|
208 david.dillard 1.34
|
209 tony 1.8 void CIMListenerService::bind()
210 {
|
211 dave.sudlik 1.48 if (_ip6Acceptor != NULL)
|
212 mike 1.41 {
|
213 dave.sudlik 1.48 _ip6Acceptor->bind();
214
215 Logger::put(
216 Logger::STANDARD_LOG,
217 System::CIMLISTENER,
218 Logger::INFORMATION,
219 "IPV6, Listening on HTTP port $0.",
220 _portNumber);
221 }
222 if (_ip4Acceptor != NULL)
223 {
224 _ip4Acceptor->bind();
|
225 kumpf 1.1
|
226 mike 1.41 Logger::put(
|
227 karl 1.49 Logger::STANDARD_LOG,
|
228 mike 1.41 System::CIMLISTENER,
|
229 karl 1.49 Logger::INFORMATION,
|
230 dave.sudlik 1.48 "IPV4, Listening on HTTP for port $0.",
|
231 mike 1.41 _portNumber);
|
232 chuck 1.20 }
|
233 tony 1.8 }
|
234 chuck 1.20
|
235 tony 1.8 void CIMListenerService::runForever()
236 {
|
237 mike 1.41 if (!_dieNow)
|
238 dj.gorey 1.14 {
|
239 kumpf 1.43 _monitor->run(500000);
240 static struct timeval lastIdleCleanupTime = {0, 0};
241 struct timeval now;
|
242 kumpf 1.44 Time::gettimeofday(&now);
|
243 kumpf 1.43 if (now.tv_sec - lastIdleCleanupTime.tv_sec > 300)
|
244 mike 1.41 {
|
245 kumpf 1.43 lastIdleCleanupTime.tv_sec = now.tv_sec;
|
246 mike 1.41 try
247 {
248 MessageQueueService::get_thread_pool()->cleanupIdleThreads();
249 }
250 catch(...)
251 {
252 // Ignore!
253 }
254 }
|
255 chuck 1.20 }
|
256 tony 1.8 }
|
257 kumpf 1.1
|
258 tony 1.8 void CIMListenerService::shutdown()
259 {
260 PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::shutdown()");
|
261 kumpf 1.1
|
262 mike 1.41 // This logic signals the thread currently executing _listener_routine()
|
263 karl 1.49 // to exit. That function deletes this instance of CIMListenerService,
264 // which deletes the _monitor member. We use a mutex to keep it from
|
265 mike 1.41 // deleting the monitor until after tickle has been called.
266 {
267 AutoMutex am(_monitorMutex);
268 _dieNow = true;
269 _monitor->tickle();
270 }
|
271 kumpf 1.1
|
272 kumpf 1.4 PEG_METHOD_EXIT();
|
273 kumpf 1.1 }
274
|
275 tony 1.8 void CIMListenerService::resume()
|
276 kumpf 1.1 {
|
277 tony 1.8 PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::resume()");
|
278 dave.sudlik 1.48 if (_ip6Acceptor != NULL)
279 {
280 _ip6Acceptor->reopenConnectionSocket();
281 }
282 if (_ip4Acceptor != NULL)
283 {
284 _ip4Acceptor->reopenConnectionSocket();
285 }
|
286 kumpf 1.4 PEG_METHOD_EXIT();
|
287 kumpf 1.1 }
288
|
289 tony 1.8 void CIMListenerService::stopClientConnection()
|
290 kumpf 1.1 {
|
291 mike 1.41 PEG_METHOD_ENTER(
292 TRC_LISTENER,
293 "CIMListenerService::stopClientConnection()");
|
294 kumpf 1.1
|
295 kumpf 1.10 // tell Monitor to stop listening for client connections
|
296 chuck 1.22 _monitor->stopListeningForConnections(true);
|
297 dave.sudlik 1.48 if (_ip6Acceptor != NULL)
298 {
299 _ip6Acceptor->closeConnectionSocket();
300 }
301 if (_ip4Acceptor != NULL)
302 {
303 _ip4Acceptor->closeConnectionSocket();
304 }
|
305 kumpf 1.4 PEG_METHOD_EXIT();
|
306 kumpf 1.1 }
307
|
308 chuck 1.23 Uint32 CIMListenerService::getOutstandingRequestCount()
309 {
|
310 dave.sudlik 1.48 Uint32 cnt = 0;
|
311 venkat.puvvada 1.50
312 if (_ip6Acceptor)
313 {
314 cnt = _ip6Acceptor->getOutstandingRequestCount();
315 }
316
317 if (_ip4Acceptor)
318 {
319 cnt += _ip4Acceptor->getOutstandingRequestCount();
320 }
|
321 dave.sudlik 1.48
322 return cnt;
|
323 chuck 1.23 }
|
324 tony 1.8
|
325 karl 1.49 CIMListenerIndicationDispatcher*
|
326 mike 1.41 CIMListenerService::getIndicationDispatcher() const
|
327 kumpf 1.1 {
|
328 david.dillard 1.32 return _dispatcher;
|
329 tony 1.8 }
|
330 david.dillard 1.34
|
331 mike 1.41 void CIMListenerService::setIndicationDispatcher(
332 CIMListenerIndicationDispatcher* dispatcher)
|
333 tony 1.8 {
|
334 david.dillard 1.32 _dispatcher = dispatcher;
|
335 kumpf 1.1 }
336
|
337 david.dillard 1.34 Uint32 CIMListenerService::getPortNumber() const
338 {
339 Uint32 portNumber = _portNumber;
340
|
341 dave.sudlik 1.48 if ((portNumber == 0) && (_ip6Acceptor != 0))
|
342 david.dillard 1.34 {
|
343 dave.sudlik 1.48 portNumber = _ip6Acceptor->getPortNumber();
|
344 david.dillard 1.34 }
|
345 venkat.puvvada 1.50 else if ((portNumber == 0) && (_ip4Acceptor != 0))
|
346 dave.sudlik 1.48 {
347 portNumber = _ip4Acceptor->getPortNumber();
348 }
|
349 david.dillard 1.34
|
350 mike 1.41 return (portNumber);
|
351 david.dillard 1.34 }
352
|
353 karl 1.49 ThreadReturnType PEGASUS_THREAD_CDECL
|
354 mike 1.41 CIMListenerService::_listener_routine(void *param)
|
355 kumpf 1.1 {
|
356 mike 1.41 CIMListenerService *svc = reinterpret_cast < CIMListenerService * >(param);
|
357 kumpf 1.1
|
358 mike 1.41 try
|
359 david.dillard 1.32 {
|
360 mike 1.41 // svc->init(); bug 1394
361 while (!svc->terminated())
362 {
|
363 mike 1.46 #if defined(PEGASUS_OS_DARWIN)
|
364 mike 1.41 pthread_testcancel();
|
365 chuck 1.20 #endif
|
366 mike 1.41 svc->runForever();
367 }
|
368 david.dillard 1.32 }
|
369 mike 1.41 catch(...)
370 {
|
371 marek 1.47 PEG_TRACE_CSTRING(TRC_SERVER, Tracer::LEVEL2,
|
372 mike 1.41 "Unknown exception thrown in _listener_routine.");
373 }
374
375 // CAUTION: deleting the service also deletes the monitor whose tickle()
376 // method may still be executing in another thread. This line of code was
377 // most likely reached when the CIMListenerService::shutdown() method set
378 // _dieNow to true and called Monitor::tickle(). We must wait until we
379 // can obtain the _monitorMutex, indicating that we are no longer inside
380 // Monitor::tickle().
|
381 mike 1.42 svc->_monitorMutex.lock();
|
382 mike 1.41 svc->_monitorMutex.unlock();
383 delete svc;
384
|
385 david.dillard 1.32 return 0;
|
386 tony 1.8 }
387
|
388 mike 1.41 ////////////////////////////////////////////////////////////////////////////////
389 //
|
390 tony 1.8 // CIMListenerRep
|
391 mike 1.41 //
392 ////////////////////////////////////////////////////////////////////////////////
393
|
394 tony 1.8 class CIMListenerRep
395 {
396 public:
|
397 mike 1.41 CIMListenerRep(Uint32 portNumber, SSLContext * sslContext = NULL);
398 ~CIMListenerRep();
|
399 tony 1.8
|
400 mike 1.41 Uint32 getPortNumber() const;
|
401 tony 1.8
|
402 mike 1.41 SSLContext *getSSLContext() const;
403 void setSSLContext(SSLContext * sslContext);
|
404 david.dillard 1.31
|
405 mike 1.41 void start();
406 void stop();
|
407 tony 1.8
|
408 mike 1.41 Boolean isAlive();
|
409 tony 1.8
|
410 mike 1.41 Boolean addConsumer(CIMIndicationConsumer * consumer);
411 Boolean removeConsumer(CIMIndicationConsumer * consumer);
|
412 tony 1.8
413 private:
|
414 mike 1.41 Boolean waitForPendingRequests(Uint32 shutdownTimeout);
|
415 chuck 1.23
|
416 mike 1.41 Uint32 _portNumber;
417 SSLContext *_sslContext;
|
418 tony 1.8
|
419 mike 1.41 CIMListenerIndicationDispatcher *_dispatcher;
420 ThreadPool *_thread_pool;
421 CIMListenerService *_svc;
422 Semaphore *_listener_sem;
|
423 tony 1.8 };
424
|
425 mike 1.41 CIMListenerRep::CIMListenerRep(
|
426 karl 1.49 Uint32 portNumber,
|
427 mike 1.41 SSLContext * sslContext)
428 :
|
429 karl 1.49 _portNumber(portNumber),
|
430 mike 1.41 _sslContext(sslContext),
|
431 karl 1.49 _dispatcher(new CIMListenerIndicationDispatcher()),
|
432 mike 1.41 _thread_pool(NULL),
|
433 karl 1.49 _svc(NULL),
|
434 mike 1.41 _listener_sem(NULL)
|
435 tony 1.8 {
436 }
|
437 david.dillard 1.31
|
438 tony 1.8 CIMListenerRep::~CIMListenerRep()
439 {
|
440 kumpf 1.51 stop();
|
441 chuck 1.20
442 delete _sslContext;
443 delete _dispatcher;
444 delete _thread_pool;
445 delete _listener_sem;
|
446 tony 1.8
|
447 mike 1.41 // don't delete _svc, this is deleted by _listener_routine
|
448 tony 1.8 }
449
450 Uint32 CIMListenerRep::getPortNumber() const
451 {
|
452 david.dillard 1.34 Uint32 portNumber;
453
|
454 mike 1.41 if (_svc == 0)
|
455 david.dillard 1.34 portNumber = _portNumber;
|
456 mike 1.41 else
457 portNumber = _svc->getPortNumber();
|
458 david.dillard 1.34
459 return portNumber;
|
460 tony 1.8 }
|
461 kumpf 1.1
|
462 mike 1.41 SSLContext *CIMListenerRep::getSSLContext() const
|
463 tony 1.8 {
|
464 david.dillard 1.31 return _sslContext;
|
465 kumpf 1.1 }
|
466 david.dillard 1.31
|
467 mike 1.41 void CIMListenerRep::setSSLContext(SSLContext * sslContext)
|
468 tony 1.8 {
|
469 david.dillard 1.31 delete _sslContext;
470 _sslContext = sslContext;
471 }
|
472 kumpf 1.1
|
473 tony 1.8 void CIMListenerRep::start()
|
474 kumpf 1.1 {
|
475 david.dillard 1.31 // spawn a thread to do this
|
476 mike 1.41 if (_thread_pool == 0)
|
477 chuck 1.20 {
|
478 mike 1.41 AutoPtr < CIMListenerService >
479 svc(new CIMListenerService(_portNumber, _sslContext));
|
480 chuck 1.20
|
481 david.dillard 1.31 svc->setIndicationDispatcher(_dispatcher);
482 svc->init();
|
483 chuck 1.20
|
484 mike 1.41 struct timeval deallocateWait = { 15, 0 };
485 AutoPtr < ThreadPool >
486 threadPool(new ThreadPool(0, "Listener", 0, 1, deallocateWait));
487 AutoPtr < Semaphore > sem(new Semaphore(0));
488
489 if (threadPool->allocate_and_awaken(
|
490 karl 1.49 svc.get(), CIMListenerService::_listener_routine, sem.get())
|
491 mike 1.41 != PEGASUS_THREAD_OK)
492 {
|
493 marek 1.52 // TBD-7646
|
494 marek 1.47 PEG_TRACE_CSTRING(
|
495 karl 1.49 TRC_SERVER,
|
496 mike 1.41 Tracer::LEVEL2,
497 "Could not allocate thread for "
498 "CIMListenerService::_listener_routine.");
499 throw
500 Exception(MessageLoaderParms(
501 "Listener.CIMListener.CANNOT_ALLOCATE_THREAD",
502 "Could not allocate thread."));
|
503 konrad.r 1.38 }
|
504 mike 1.41
505 Logger::put(
|
506 karl 1.49 Logger::STANDARD_LOG,
|
507 mike 1.41 System::CIMLISTENER,
|
508 karl 1.49 Logger::INFORMATION,
|
509 mike 1.41 "CIMListener started");
|
510 david.dillard 1.31
511 _svc = svc.release();
512 _thread_pool = threadPool.release();
513 _listener_sem = sem.release();
514 }
|
515 tony 1.8 }
|
516 kumpf 1.1
|
517 tony 1.8 void CIMListenerRep::stop()
518 {
|
519 mike 1.41 if (_thread_pool != NULL)
|
520 chuck 1.20 {
|
521 karl 1.49 //
|
522 mike 1.41 // Graceful shutdown of the listener service
|
523 karl 1.49 //
|
524 mike 1.41
525 // Block incoming export requests and unbind the port
526 _svc->stopClientConnection();
527
528 // Wait until pending export requests in the server are done.
529 waitForPendingRequests(10);
530
531 // Shutdown the CIMListenerService
532 _svc->shutdown();
|
533 chuck 1.20
|
534 mike 1.41 // Wait for the _listener_routine thread to exit.
535 // The thread could be delivering an export, so give it 3sec.
536 // Note that _listener_routine deletes the CIMListenerService,
537 // so no need to delete _svc.
538 try
539 {
540 _listener_sem->time_wait(3000);
541 }
542 catch(const TimeOut &)
543 {
544 // No need to do anything, the thread pool will be deleted below
545 // to cancel the _listener_routine thread if it is still running.
546 }
|
547 david.dillard 1.31
|
548 mike 1.41 delete _listener_sem;
549 _listener_sem = NULL;
|
550 chuck 1.20
|
551 karl 1.49 // Delete the thread pool. This cancels the listener thread if it is
|
552 mike 1.41 // still
553 // running.
554 delete _thread_pool;
555 _thread_pool = NULL;
556
557 Logger::put(
558 Logger::STANDARD_LOG, System::CIMLISTENER,
559 Logger::INFORMATION, "CIMListener stopped");
560 }
|
561 kumpf 1.1 }
562
|
563 tony 1.8 Boolean CIMListenerRep::isAlive()
|
564 kumpf 1.1 {
|
565 mike 1.41 return (_thread_pool != NULL) ? true : false;
|
566 tony 1.8 }
|
567 kumpf 1.1
|
568 mike 1.41 Boolean CIMListenerRep::addConsumer(CIMIndicationConsumer * consumer)
|
569 tony 1.8 {
|
570 mike 1.41 return _dispatcher->addConsumer(consumer);
|
571 tony 1.8 }
|
572 mike 1.41
573 Boolean CIMListenerRep::removeConsumer(CIMIndicationConsumer * consumer)
|
574 tony 1.8 {
|
575 mike 1.41 return _dispatcher->removeConsumer(consumer);
|
576 tony 1.8 }
|
577 kumpf 1.1
|
578 chuck 1.23 Boolean CIMListenerRep::waitForPendingRequests(Uint32 shutdownTimeout)
579 {
|
580 mike 1.41 // Wait for 10 sec max
581 Uint32 reqCount;
582 Uint32 countDown = shutdownTimeout * 10;
583
584 for (; countDown > 0; countDown--)
585 {
586 reqCount = _svc->getOutstandingRequestCount();
587 if (reqCount > 0)
|
588 mike 1.42 Threads::sleep(100);
|
589 mike 1.41 else
590 return true;
591 }
|
592 david.dillard 1.31
|
593 mike 1.41 return false;
|
594 david.dillard 1.31 }
|
595 chuck 1.23
|
596 tony 1.8 /////////////////////////////////////////////////////////////////////////////
|
597 mike 1.41 //
|
598 tony 1.8 // CIMListener
|
599 mike 1.41 //
|
600 tony 1.8 /////////////////////////////////////////////////////////////////////////////
|
601 mike 1.41
602 CIMListener::CIMListener(
|
603 karl 1.49 Uint32 portNumber,
604 SSLContext * sslContext)
|
605 mike 1.41 :
606 _rep(new CIMListenerRep(portNumber, sslContext))
|
607 tony 1.8 {
608 }
|
609 mike 1.41
|
610 tony 1.8 CIMListener::~CIMListener()
611 {
|
612 mike 1.41 if (_rep != NULL)
613 delete static_cast < CIMListenerRep * >(_rep);
614 _rep = NULL;
|
615 tony 1.8 }
|
616 david.dillard 1.31
|
617 tony 1.8 Uint32 CIMListener::getPortNumber() const
618 {
|
619 mike 1.41 return static_cast < CIMListenerRep * >(_rep)->getPortNumber();
|
620 kumpf 1.1 }
621
|
622 mike 1.41 SSLContext *CIMListener::getSSLContext() const
|
623 tony 1.8 {
|
624 mike 1.41 return static_cast < CIMListenerRep * >(_rep)->getSSLContext();
|
625 tony 1.8 }
|
626 mike 1.41
627 void CIMListener::setSSLContext(SSLContext * sslContext)
|
628 tony 1.8 {
|
629 mike 1.41 static_cast < CIMListenerRep * >(_rep)->setSSLContext(sslContext);
|
630 tony 1.8 }
|
631 mike 1.41
|
632 tony 1.8 void CIMListener::start()
|
633 kumpf 1.1 {
|
634 mike 1.41 static_cast < CIMListenerRep * >(_rep)->start();
|
635 tony 1.8 }
|
636 mike 1.41
|
637 tony 1.8 void CIMListener::stop()
638 {
|
639 mike 1.41 static_cast < CIMListenerRep * >(_rep)->stop();
|
640 tony 1.8 }
|
641 kumpf 1.1
|
642 aruran.ms 1.35 Boolean CIMListener::isAlive() const
|
643 tony 1.8 {
|
644 mike 1.41 return static_cast < CIMListenerRep * >(_rep)->isAlive();
|
645 tony 1.8 }
|
646 kumpf 1.1
|
647 mike 1.41 Boolean CIMListener::addConsumer(CIMIndicationConsumer * consumer)
|
648 tony 1.8 {
|
649 mike 1.41 return static_cast < CIMListenerRep * >(_rep)->addConsumer(consumer);
|
650 tony 1.8 }
|
651 mike 1.41
652 Boolean CIMListener::removeConsumer(CIMIndicationConsumer * consumer)
|
653 tony 1.8 {
|
654 mike 1.41 return static_cast < CIMListenerRep * >(_rep)->removeConsumer(consumer);
|
655 kumpf 1.1 }
656
657 PEGASUS_NAMESPACE_END
|