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

Diff for /pegasus/src/Pegasus/Listener/CIMListener.cpp between version 1.4 and 1.60

version 1.4, 2002/06/03 19:32:35 version 1.60, 2015/06/10 12:36:02
Line 1 
Line 1 
 //%/////////////////////////////////////////////////////////////////////////////  //%LICENSE////////////////////////////////////////////////////////////////
   //
   // Licensed to The Open Group (TOG) under one or more contributor license
   // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
   // this work for additional information regarding copyright ownership.
   // Each contributor licenses this file to you under the OpenPegasus Open
   // Source License; you may not use this file except in compliance with the
   // License.
   //
   // Permission is hereby granted, free of charge, to any person obtaining a
   // copy of this software and associated documentation files (the "Software"),
   // to deal in the Software without restriction, including without limitation
   // the rights to use, copy, modify, merge, publish, distribute, sublicense,
   // and/or sell copies of the Software, and to permit persons to whom the
   // Software is furnished to do so, subject to the following conditions:
   //
   // The above copyright notice and this permission notice shall be included
   // in all copies or substantial portions of the Software.
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 // The Open Group, Tivoli Systems  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy  //////////////////////////////////////////////////////////////////////////
 // of this software and associated documentation files (the "Software"), to  
 // deal in the Software without restriction, including without limitation the  
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  
 // sell copies of the Software, and to permit persons to whom the Software is  
 // furnished to do so, subject to the following conditions:  
 //  
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN  
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED  
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT  
 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  
 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  
 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN  
 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
 //  
 //==============================================================================  
 //  
 // Author: Mike Brasher (mbrasher@bmc.com)  
 //  
 // Modified By:  
 //         Mike Day (mdday@us.ibm.com)s  
 //         Nitin Upasani, Hewlett-Packard Company (Nitin_Upasani@hp.com)  
 //         Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)  
 //         Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)  
 //         Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)  
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #include <Pegasus/Common/Config.h>  #include "CIMListener.h"
   #include <Pegasus/Common/Exception.h>
 #include <iostream>  #include <Pegasus/Common/SSLContext.h>
 #include <cassert>  #include <Pegasus/Common/Monitor.h>
 #include <cstdio>  
 #include <cctype>  
 #include <ctime>  
 #include <Pegasus/Common/FileSystem.h>  
 #include <Pegasus/Common/HTTPAcceptor.h> #include <Pegasus/Common/HTTPAcceptor.h>
 #include <Pegasus/Common/Tracer.h>  #include <Pegasus/Common/HostAddress.h>
 #include <Pegasus/Common/PegasusVersion.h> #include <Pegasus/Common/PegasusVersion.h>
   #include <Pegasus/Common/MessageLoader.h>
 #include <Pegasus/Repository/CIMRepository.h>  #include <Pegasus/Common/Time.h>
 #include <Pegasus/ExportServer/CIMExportRequestDispatcher.h>  
 #include <Pegasus/ExportServer/CIMExportResponseEncoder.h> #include <Pegasus/ExportServer/CIMExportResponseEncoder.h>
 #include <Pegasus/ExportServer/CIMExportRequestDecoder.h> #include <Pegasus/ExportServer/CIMExportRequestDecoder.h>
   #include <Pegasus/Consumer/CIMIndicationConsumer.h>
   #include <Pegasus/Listener/CIMListenerIndicationDispatcher.h>
  
 #include "CIMListener.h"  PEGASUS_NAMESPACE_BEGIN
  
 #define DDD(X) // X  ////////////////////////////////////////////////////////////////////////////////
   //
   // CIMListenerService
   //
   ////////////////////////////////////////////////////////////////////////////////
  
 PEGASUS_USING_STD;  class CIMListenerService
   {
   public:
       CIMListenerService(
           const String &listenAddress,
           Uint32 portNumber,
           SSLContext * sslContext = NULL);
       CIMListenerService(Uint32 portNumber, SSLContext * sslContext = NULL);
       CIMListenerService(CIMListenerService & svc);
       ~CIMListenerService();
   
       void init();
   
       /** bind to the port
       */
       void bind();
   
       /** runForever Main runloop for the server.
       */
       void runForever();
   
       /** Call to gracefully shutdown the server.  The server connection socket
           will be closed to disable new connections from clients.
       */
       void stopClientConnection();
   
       /** Call to gracefully shutdown the server.  It is called when the server
           has been stopped and is ready to be shutdown.  Next time runForever()
           is called, the server shuts down.
       */
       void shutdown();
   
       /** Return true if the server has shutdown, false otherwise.
       */
       Boolean terminated() const
       {
           return _dieNow;
       };
  
 PEGASUS_NAMESPACE_BEGIN      /** Call to resume the sever.
       */
       void resume();
   
       /** Call to set the CIMServer state.  Also inform the appropriate
           message queues about the current state of the CIMServer.
       */
       void setState(Uint32 state);
   
       Uint32 getOutstandingRequestCount();
   
       /** Returns the indication listener dispatcher
       */
       CIMListenerIndicationDispatcher *getIndicationDispatcher() const;
   
       /** Returns the indication listener dispatcher
       */
       void setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher);
   
       /** Returns the bind address.
       */
       String getListenAddress() const;
   
       /** Returns the port number being used.
       */
       Uint32 getPortNumber() const;
   
       static ThreadReturnType PEGASUS_THREAD_CDECL
       _listener_routine(void *param);
   
   private:
       String _listenAddress;
       Uint32 _portNumber;
       SSLContext *_sslContext;
       ReadWriteSem _sslContextObjectLock;
       Monitor *_monitor;
       Mutex _monitorMutex;
       HTTPAcceptor *_ip6Acceptor;
       HTTPAcceptor *_ip4Acceptor;
       Boolean _dieNow;
       CIMListenerIndicationDispatcher *_dispatcher;
       CIMExportResponseEncoder *_responseEncoder;
       CIMExportRequestDecoder *_requestDecoder;
   };
   
   CIMListenerService::CIMListenerService(
       const String &listenAddress,
       Uint32 portNumber,
       SSLContext * sslContext)
       :
       _listenAddress(listenAddress),
       _portNumber(portNumber),
       _sslContext(sslContext),
       _monitor(NULL),
       _ip6Acceptor(NULL),
       _ip4Acceptor(NULL),
       _dieNow(false),
       _dispatcher(NULL),
       _responseEncoder(NULL),
       _requestDecoder(NULL)
   {
   }
  
 CIMListener::CIMListener(  CIMListenerService::CIMListenerService(
     Monitor* monitor,      Uint32 portNumber,
     const String& rootPath,      SSLContext * sslContext)
     Boolean dynamicReg,      :
     Boolean staticConsumers,      _listenAddress(),
     Boolean persistence)      _portNumber(portNumber),
     : _dieNow(false), _rootPath(rootPath),      _sslContext(sslContext),
     _dynamicReg(dynamicReg),      _monitor(NULL),
     _staticConsumers(staticConsumers),      _ip6Acceptor(NULL),
     _persistence(persistence)      _ip4Acceptor(NULL),
       _dieNow(false),
       _dispatcher(NULL),
       _responseEncoder(NULL),
       _requestDecoder(NULL)
 { {
     PEG_METHOD_ENTER(TRC_SERVER, "CIMListener::CIMListener()");  }
  
     // -- Save the monitor or create a new one:  CIMListenerService::CIMListenerService(CIMListenerService & svc) :
       _listenAddress(svc._listenAddress),
       _portNumber(svc._portNumber),
       _sslContext(svc._sslContext),
       _monitor(NULL),
       _ip6Acceptor(NULL),
       _ip4Acceptor(NULL),
       _dieNow(svc._dieNow),
       _dispatcher(NULL),
       _responseEncoder(NULL),
       _requestDecoder(NULL)
   {
   }
  
     _monitor = monitor;  CIMListenerService::~CIMListenerService()
   {
       delete _responseEncoder;
       delete _requestDecoder;
       delete _ip6Acceptor;
       delete _ip4Acceptor;
       delete _monitor;
   }
  
     // -- Create a CIMListenerState object:  void CIMListenerService::init()
   {
       PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::init");
  
     _cimExportRequestDispatcher      if (NULL == _monitor)
         = new CIMExportRequestDispatcher(dynamicReg, staticConsumers, persistence);          _monitor = new Monitor();
  
     _cimExportResponseEncoder      // _dispatcher = new CIMListenerIndicationDispatcher();
         = new CIMExportResponseEncoder;  
  
     _cimExportRequestDecoder = new CIMExportRequestDecoder(      if (NULL == _responseEncoder)
         _cimExportRequestDispatcher,          _responseEncoder = new CIMExportResponseEncoder();
         _cimExportResponseEncoder->getQueueId());  
  
     SSLContext * sslcontext = NULL;      if (NULL == _requestDecoder)
       {
           _requestDecoder = new CIMExportRequestDecoder(
               _dispatcher, _responseEncoder->getQueueId());
       }
  
     _acceptor = new HTTPAcceptor(_monitor, _cimExportRequestDecoder, sslcontext);      HostAddress listenAddress;
       Boolean listenAddressEmpty = _listenAddress == String::EMPTY;
       if (!listenAddressEmpty)
           listenAddress.setHostAddress(_listenAddress);
   
   #ifdef PEGASUS_ENABLE_IPV6
       if (System::isIPv6StackActive() &&
          (listenAddressEmpty ||
          (listenAddress.isValid() &&
           listenAddress.getAddressType() == HostAddress::AT_IPV6)))
       {
           if (NULL == _ip6Acceptor)
           {
               if (NULL == _sslContext)
               {
                   _ip6Acceptor = new HTTPAcceptor(
                           _monitor, _requestDecoder,
                           HTTPAcceptor::IPV6_CONNECTION,
                           _portNumber, 0, 0,
                           listenAddressEmpty ? 0 : &listenAddress);
               }
               else
               {
                   _ip6Acceptor = new HTTPAcceptor(
                           _monitor, _requestDecoder,
                           HTTPAcceptor::IPV6_CONNECTION,
                           _portNumber, _sslContext, &_sslContextObjectLock,
                           listenAddressEmpty ? 0 : &listenAddress);
               }
           }
       }
   #ifndef PEGASUS_OS_TYPE_WINDOWS
       else
   #endif
   #endif
       if (NULL == _ip4Acceptor)
       {
           if (NULL == _sslContext)
           {
               _ip4Acceptor = new HTTPAcceptor(
                       _monitor, _requestDecoder,
                       HTTPAcceptor::IPV4_CONNECTION,
                       _portNumber, 0, 0,
                       listenAddressEmpty ? 0 : &listenAddress);
           }
           else
           {
               _ip4Acceptor = new HTTPAcceptor(
                       _monitor, _requestDecoder,
                       HTTPAcceptor::IPV4_CONNECTION,
                       _portNumber, _sslContext, &_sslContextObjectLock,
                       listenAddressEmpty ? 0 : &listenAddress);
           }
       }
       bind();
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
  
 CIMListener::~CIMListener()  void CIMListenerService::bind()
   {
       if (_ip6Acceptor != NULL)
 { {
     PEG_METHOD_ENTER(TRC_SERVER, "CIMListener::~CIMListener()");          _ip6Acceptor->bind();
  
     // Note: do not delete the acceptor because it belongs to the Monitor          Logger::put(
     // which takes care of disposing of it.              Logger::STANDARD_LOG,
               System::CIMLISTENER,
               Logger::INFORMATION,
               "IPV6, Listening on HTTP port $0.",
               _portNumber);
       }
       if (_ip4Acceptor != NULL)
       {
           _ip4Acceptor->bind();
  
     PEG_METHOD_EXIT();          Logger::put(
               Logger::STANDARD_LOG,
               System::CIMLISTENER,
               Logger::INFORMATION,
               "IPV4, Listening on HTTP for port $0.",
               _portNumber);
       }
 } }
  
 void CIMListener::bind(Uint32 port)  void CIMListenerService::runForever()
 { {
     PEG_METHOD_ENTER(TRC_SERVER, "CIMListener::bind()");      if (!_dieNow)
       {
           _monitor->run(500000);
           static struct timeval lastIdleCleanupTime = {0, 0};
           struct timeval now;
           Time::gettimeofday(&now);
           if (now.tv_sec - lastIdleCleanupTime.tv_sec > 300)
           {
               lastIdleCleanupTime.tv_sec = now.tv_sec;
               try
               {
                   MessageQueueService::get_thread_pool()->cleanupIdleThreads();
               }
               catch(...)
               {
                   // Ignore!
               }
           }
       }
   }
  
     // not the best place to build the service url, but it works for now  void CIMListenerService::shutdown()
     // because the address string is accessible  mdday  {
       PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::shutdown()");
  
     _acceptor->bind(port);      // This logic signals the thread currently executing _listener_routine()
       // to exit. That function deletes this instance of CIMListenerService,
       // which deletes the _monitor member. We use a mutex to keep it from
       // deleting the monitor until after tickle has been called.
       {
           AutoMutex am(_monitorMutex);
           _dieNow = true;
           _monitor->tickle();
       }
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
  
 void CIMListener::runForever()  void CIMListenerService::resume()
 { {
     //ATTN: Do not add Trace code in this method.      PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::resume()");
     if(!_dieNow)      if (_ip6Acceptor != NULL)
         _monitor->run(100);      {
           _ip6Acceptor->reopenConnectionSocket();
       }
       if (_ip4Acceptor != NULL)
       {
           _ip4Acceptor->reopenConnectionSocket();
       }
       PEG_METHOD_EXIT();
 } }
  
 void CIMListener::stopClientConnection()  void CIMListenerService::stopClientConnection()
 { {
     PEG_METHOD_ENTER(TRC_SERVER, "CIMListener::stopClientConnection()");      PEG_METHOD_ENTER(
           TRC_LISTENER,
           "CIMListenerService::stopClientConnection()");
   
       // tell Monitor to stop listening for client connections
       _monitor->stopListeningForConnections(true);
       if (_ip6Acceptor != NULL)
       {
           _ip6Acceptor->closeConnectionSocket();
       }
       if (_ip4Acceptor != NULL)
       {
           _ip4Acceptor->closeConnectionSocket();
       }
       PEG_METHOD_EXIT();
   }
  
     _acceptor->closeConnectionSocket();  Uint32 CIMListenerService::getOutstandingRequestCount()
   {
       Uint32 cnt = 0;
  
     PEG_METHOD_EXIT();      if (_ip6Acceptor)
       {
           cnt = _ip6Acceptor->getOutstandingRequestCount();
 } }
  
 void CIMListener::shutdown()      if (_ip4Acceptor)
 { {
     PEG_METHOD_ENTER(TRC_SERVER, "CIMListener::shutdown()");          cnt += _ip4Acceptor->getOutstandingRequestCount();
       }
  
     _dieNow = true;      return cnt;
   }
  
     PEG_METHOD_EXIT();  CIMListenerIndicationDispatcher*
   CIMListenerService::getIndicationDispatcher() const
   {
       return _dispatcher;
 } }
  
 void CIMListener::resume()  void CIMListenerService::setIndicationDispatcher(
       CIMListenerIndicationDispatcher* dispatcher)
 { {
     PEG_METHOD_ENTER(TRC_SERVER, "CIMListener::resume()");      _dispatcher = dispatcher;
   }
  
     _acceptor->reopenConnectionSocket();  String CIMListenerService::getListenAddress() const
   {
       bool listenAddressEmpty = _listenAddress == String::EMPTY;
  
     PEG_METHOD_EXIT();      if (listenAddressEmpty && _ip6Acceptor != 0)
           return _ip6Acceptor->getListenAddress();
       else if (listenAddressEmpty && _ip4Acceptor != 0)
           return _ip4Acceptor->getListenAddress();
   
       return _listenAddress;
 } }
  
 CIMExportRequestDispatcher* CIMListener::getDispatcher()  Uint32 CIMListenerService::getPortNumber() const
 { {
     PEG_METHOD_ENTER(TRC_SERVER, "CIMListener::getDispatcher()");      Uint32 portNumber = _portNumber;
  
     PEG_METHOD_EXIT();      if ((portNumber == 0) && (_ip6Acceptor != 0))
       {
           portNumber = _ip6Acceptor->getPortNumber();
       }
       else if ((portNumber == 0) && (_ip4Acceptor != 0))
       {
           portNumber = _ip4Acceptor->getPortNumber();
       }
  
     return _cimExportRequestDispatcher;      return (portNumber);
 } }
  
 Uint32 CIMListener::getOutstandingRequestCount()  ThreadReturnType PEGASUS_THREAD_CDECL
   CIMListenerService::_listener_routine(void *param)
 { {
     PEG_METHOD_ENTER(TRC_SERVER, "CIMListener::getOutstandingRequestCount()");      CIMListenerService *svc = reinterpret_cast < CIMListenerService * >(param);
  
     PEG_METHOD_EXIT();      try
       {
           // svc->init(); bug 1394
           while (!svc->terminated())
           {
   #if defined(PEGASUS_OS_DARWIN)
               pthread_testcancel();
   #endif
               svc->runForever();
           }
       }
       catch(...)
       {
           PEG_TRACE_CSTRING(TRC_SERVER, Tracer::LEVEL1,
                         "Unknown exception thrown in _listener_routine.");
       }
   
       // CAUTION: deleting the service also deletes the monitor whose tickle()
       // method may still be executing in another thread. This line of code was
       // most likely reached when the CIMListenerService::shutdown() method set
       // _dieNow to true and called Monitor::tickle(). We must wait until we
       // can obtain the _monitorMutex, indicating that we are no longer inside
       // Monitor::tickle().
       svc->_monitorMutex.lock();
       svc->_monitorMutex.unlock();
       delete svc;
   
       return 0;
   }
   
   ////////////////////////////////////////////////////////////////////////////////
   //
   // CIMListenerRep
   //
   ////////////////////////////////////////////////////////////////////////////////
   
   class CIMListenerRep
   {
   public:
       CIMListenerRep(
           const String &listenAddress,
           Uint32 portNumber,
           SSLContext* sslContext = NULL);
       CIMListenerRep(Uint32 portNumber, SSLContext * sslContext = NULL);
       ~CIMListenerRep();
   
       String getListenAddress() const;
       Uint32 getPortNumber() const;
   
       SSLContext *getSSLContext() const;
       void setSSLContext(SSLContext * sslContext);
   
       void start();
       void stop();
   
       Boolean isAlive();
   
       Boolean addConsumer(CIMIndicationConsumer * consumer);
       Boolean removeConsumer(CIMIndicationConsumer * consumer);
   
   private:
       Boolean waitForPendingRequests(Uint32 shutdownTimeout);
   
       String _listenAddress;
       Uint32 _portNumber;
       SSLContext *_sslContext;
   
       CIMListenerIndicationDispatcher *_dispatcher;
       ThreadPool *_thread_pool;
       CIMListenerService *_svc;
       Semaphore *_listener_sem;
   };
   
   CIMListenerRep::CIMListenerRep(
       const String &listenAddress,
       Uint32 portNumber,
       SSLContext * sslContext)
       :
       _listenAddress(listenAddress),
       _portNumber(portNumber),
       _sslContext(sslContext),
       _dispatcher(new CIMListenerIndicationDispatcher()),
       _thread_pool(NULL),
       _svc(NULL),
       _listener_sem(NULL)
   {
   }
   
   CIMListenerRep::CIMListenerRep(
       Uint32 portNumber,
       SSLContext * sslContext)
       :
       _listenAddress(),
       _portNumber(portNumber),
       _sslContext(sslContext),
       _dispatcher(new CIMListenerIndicationDispatcher()),
       _thread_pool(NULL),
       _svc(NULL),
       _listener_sem(NULL)
   {
   }
   
   CIMListenerRep::~CIMListenerRep()
   {
       stop();
   
       delete _sslContext;
       delete _dispatcher;
       delete _thread_pool;
       delete _listener_sem;
   
       // don't delete _svc, this is deleted by _listener_routine
   }
   
   String CIMListenerRep::getListenAddress() const
   {
       return !_svc ? _listenAddress : _svc->getListenAddress();
   }
   
   Uint32 CIMListenerRep::getPortNumber() const
   {
       Uint32 portNumber;
   
       if (_svc == 0)
           portNumber = _portNumber;
       else
           portNumber = _svc->getPortNumber();
   
       return portNumber;
   }
   
   SSLContext *CIMListenerRep::getSSLContext() const
   {
       return _sslContext;
   }
   
   void CIMListenerRep::setSSLContext(SSLContext * sslContext)
   {
       delete _sslContext;
       _sslContext = sslContext;
   }
   
   void CIMListenerRep::start()
   {
       // spawn a thread to do this
       if (_thread_pool == 0)
       {
           AutoPtr < CIMListenerService >
               svc(new CIMListenerService(_listenAddress, _portNumber,
                       _sslContext));
   
           svc->setIndicationDispatcher(_dispatcher);
           svc->init();
   
           struct timeval deallocateWait = { 15, 0 };
           AutoPtr < ThreadPool >
               threadPool(new ThreadPool(0, "Listener", 0, 1, deallocateWait));
           AutoPtr < Semaphore > sem(new Semaphore(0));
   
           if (threadPool->allocate_and_awaken(
               svc.get(), CIMListenerService::_listener_routine, sem.get())
               != PEGASUS_THREAD_OK)
           {
               PEG_TRACE_CSTRING(
                   TRC_SERVER,
                   Tracer::LEVEL1,
                   "Could not allocate thread for "
                   "CIMListenerService::_listener_routine.");
               throw
                   Exception(MessageLoaderParms(
                       "Listener.CIMListener.CANNOT_ALLOCATE_THREAD",
                       "Could not allocate thread."));
           }
   
           Logger::put(
               Logger::STANDARD_LOG,
               System::CIMLISTENER,
               Logger::INFORMATION,
               "CIMListener started");
   
           _svc = svc.release();
           _thread_pool = threadPool.release();
           _listener_sem = sem.release();
       }
   }
   
   void CIMListenerRep::stop()
   {
       if (_thread_pool != NULL)
       {
           //
           // Graceful shutdown of the listener service
           //
   
           // Block incoming export requests and unbind the port
           _svc->stopClientConnection();
   
           // Wait until pending export requests in the server are done.
           waitForPendingRequests(10);
  
     return (_acceptor->getOutstandingRequestCount());          // Shutdown the CIMListenerService
           _svc->shutdown();
   
           // Wait for the _listener_routine thread to exit.
           // The thread could be delivering an export, so give it 3sec.
           // Note that _listener_routine deletes the CIMListenerService,
           // so no need to delete _svc.
           if (!_listener_sem->time_wait(3000))
           {
               // No need to do anything, the thread pool will be deleted below
               // to cancel the _listener_routine thread if it is still running.
           }
   
           delete _listener_sem;
           _listener_sem = NULL;
   
           // Delete the thread pool.  This cancels the listener thread if it is
           // still
           // running.
           delete _thread_pool;
           _thread_pool = NULL;
   
           Logger::put(
               Logger::STANDARD_LOG, System::CIMLISTENER,
               Logger::INFORMATION, "CIMListener stopped");
       }
   }
   
   Boolean CIMListenerRep::isAlive()
   {
       return (_thread_pool != NULL) ? true : false;
   }
   
   Boolean CIMListenerRep::addConsumer(CIMIndicationConsumer * consumer)
   {
       return _dispatcher->addConsumer(consumer);
   }
   
   Boolean CIMListenerRep::removeConsumer(CIMIndicationConsumer * consumer)
   {
       return _dispatcher->removeConsumer(consumer);
   }
   
   Boolean CIMListenerRep::waitForPendingRequests(Uint32 shutdownTimeout)
   {
       // Wait for 10 sec max
       Uint32 reqCount;
       Uint32 countDown = shutdownTimeout * 10;
   
       for (; countDown > 0; countDown--)
       {
           reqCount = _svc->getOutstandingRequestCount();
           if (reqCount > 0)
               Threads::sleep(100);
           else
               return true;
       }
   
       return false;
   }
   
   /////////////////////////////////////////////////////////////////////////////
   //
   // CIMListener
   //
   /////////////////////////////////////////////////////////////////////////////
   
   CIMListener::CIMListener(
       const String &listenAddress,
       Uint32 portNumber,
       SSLContext* sslContext)
       :
       _rep(new CIMListenerRep(listenAddress, portNumber, sslContext))
   {
   }
   
   CIMListener::CIMListener(
       Uint32 portNumber,
       SSLContext * sslContext)
       :
       _rep(new CIMListenerRep(portNumber, sslContext))
   {
   }
   
   CIMListener::~CIMListener()
   {
       if (_rep != NULL)
           delete static_cast < CIMListenerRep * >(_rep);
       _rep = NULL;
   }
   
   String CIMListener::getListenAddress() const
   {
       return static_cast < CIMListenerRep * >(_rep)->getListenAddress();
   }
   
   Uint32 CIMListener::getPortNumber() const
   {
       return static_cast < CIMListenerRep * >(_rep)->getPortNumber();
   }
   
   SSLContext *CIMListener::getSSLContext() const
   {
       return static_cast < CIMListenerRep * >(_rep)->getSSLContext();
   }
   
   void CIMListener::setSSLContext(SSLContext * sslContext)
   {
       static_cast < CIMListenerRep * >(_rep)->setSSLContext(sslContext);
   }
   
   void CIMListener::start()
   {
       static_cast < CIMListenerRep * >(_rep)->start();
   }
   
   void CIMListener::stop()
   {
       static_cast < CIMListenerRep * >(_rep)->stop();
   }
   
   Boolean CIMListener::isAlive() const
   {
       return static_cast < CIMListenerRep * >(_rep)->isAlive();
   }
   
   Boolean CIMListener::addConsumer(CIMIndicationConsumer * consumer)
   {
       return static_cast < CIMListenerRep * >(_rep)->addConsumer(consumer);
   }
   
   Boolean CIMListener::removeConsumer(CIMIndicationConsumer * consumer)
   {
       return static_cast < CIMListenerRep * >(_rep)->removeConsumer(consumer);
 } }
  
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.4  
changed lines
  Added in v.1.60

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2