(file) Return to CIMListener.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Listener

  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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2