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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2