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