(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.2 and 1.14

version 1.2, 2002/04/20 21:15:30 version 1.14, 2004/01/29 20:45:58
Line 1 
Line 1 
 //%/////////////////////////////////////////////////////////////////////////////  //%2003////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001 BMC Software, Hewlett-Packard Company, IBM,  // Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development
 // The Open Group, Tivoli Systems  // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
   // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
   // IBM Corp.; EMC Corporation, The Open Group.
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
Line 21 
Line 23 
 // //
 //============================================================================== //==============================================================================
 // //
 // Author: Mike Brasher (mbrasher@bmc.com)  // Author: Dong Xiang, EMC Corporation (xiang_dong@emc.com)
 // //
 // Modified By:  // Modified By:   Dan Gorey (djgorey@us.ibm.com)
 //         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 <iostream>  #include <Pegasus/Common/Exception.h>
 #include <cassert>  #include <Pegasus/Common/SSLContext.h>
 #include <cstdio>  #include <Pegasus/Common/Monitor.h>
 #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/PegasusVersion.h> #include <Pegasus/Common/PegasusVersion.h>
  
 #include <Pegasus/Repository/CIMRepository.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 "CIMListener.h"  #include <Pegasus/Consumer/CIMIndicationConsumer.h>
   #include <Pegasus/Listener/CIMListenerIndicationDispatcher.h>
 #define DDD(X) // X  
   
 PEGASUS_USING_STD;  
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
   /////////////////////////////////////////////////////////////////////////////
   // CIMListenerService
   /////////////////////////////////////////////////////////////////////////////
   class CIMListenerService
   {
   public:
           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() { return _dieNow; };
   
           /** 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);
   
           static PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL _listener_routine(void *param);
   
   private:
           Uint32                  _portNumber;
           SSLContext* _sslContext;
     #ifdef PEGASUS_USE_23HTTPMONITOR
           Monitor*                                _monitor;
     HTTPAcceptor*   _acceptor;
     #else
           monitor_2*                              _monitor;
     pegasus_acceptor*   _acceptor;
     #endif
   
     Boolean                                       _dieNow;
   
     CIMListenerIndicationDispatcher* _dispatcher;
   
     CIMExportResponseEncoder* _responseEncoder;
     CIMExportRequestDecoder*  _requestDecoder;
   
   };
   
   CIMListenerService::CIMListenerService(Uint32 portNumber, SSLContext* sslContext)
   :_portNumber(portNumber)
   ,_sslContext(sslContext)
   ,_monitor(NULL)
   ,_acceptor(NULL)
   ,_dieNow(false)
   ,_dispatcher(NULL)
   ,_responseEncoder(NULL)
   ,_requestDecoder(NULL)
   {
   }
  
 CIMListener::CIMListener(  CIMListenerService::CIMListenerService(CIMListenerService& svc)
     Monitor* monitor,  :_portNumber(svc._portNumber)
     const String& rootPath,  ,_sslContext(svc._sslContext)
     Boolean dynamicReg,  ,_monitor(NULL)
     Boolean staticConsumers,  ,_acceptor(NULL)
     Boolean persistence)  ,_dieNow(svc._dieNow)
     : _dieNow(false), _rootPath(rootPath),  ,_dispatcher(NULL)
     _dynamicReg(dynamicReg),  ,_responseEncoder(NULL)
     _staticConsumers(staticConsumers),  ,_requestDecoder(NULL)
     _persistence(persistence)  {
   }
   CIMListenerService::~CIMListenerService()
 { {
     const char METHOD_NAME[] = "CIMListener::CIMListener()";          // if port is alive, clean up the port
           //if(_sslContext!=NULL)
           //      delete _sslContext;
  
     PEG_FUNC_ENTER(TRC_SERVER, METHOD_NAME);          if(_responseEncoder!=NULL)
                   delete _responseEncoder;
  
     // -- Save the monitor or create a new one:          if(_requestDecoder!=NULL)
                   delete _requestDecoder;
  
     _monitor = monitor;          //if(_dispatcher!=NULL)
           //      delete _dispatcher;
  
     // -- Create a CIMListenerState object:          if(_monitor!=NULL)
                   delete _monitor;
  
     _cimExportRequestDispatcher          if(_acceptor!=NULL)
         = new CIMExportRequestDispatcher(dynamicReg, staticConsumers, persistence);                  delete _acceptor;
   }
  
     _cimExportResponseEncoder  void CIMListenerService::init()
         = new CIMExportResponseEncoder;  {
           PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::init");
  
     _cimExportRequestDecoder = new CIMExportRequestDecoder(    #ifdef PEGASUS_USE_23HTTPMONITOR
         _cimExportRequestDispatcher,    _monitor = new Monitor(true);
         _cimExportResponseEncoder->getQueueId());    #else
     _monitor = new monitor_2();
     #endif
   
           //_dispatcher = new CIMListenerIndicationDispatcher();
   
           _responseEncoder = new CIMExportResponseEncoder();
     _requestDecoder = new CIMExportRequestDecoder(
                   _dispatcher,
                   _responseEncoder->getQueueId());
   
     #ifdef PEGASUS_USE_23HTTPMONITOR
     _acceptor = new HTTPAcceptor(
                    _monitor,
                    _requestDecoder,
                    false,
                    _portNumber,
                    _sslContext);
     #else
     _acceptor = new pegasus_acceptor(_monitor,
                      _requestDecoder,
                      false,
                      _portNumber,
                      _sslContext);
     #endif
  
     SSLContext * sslcontext = NULL;          bind();
  
     _acceptor = new HTTPAcceptor(_monitor, _cimExportRequestDecoder, sslcontext);      PEG_METHOD_EXIT();
   }
   void CIMListenerService::bind()
   {
           if(_acceptor!=NULL)
           { // Bind to the port
                   _acceptor->bind();
   
                   PEGASUS_STD(cout) << "Listening on HTTP port " << _portNumber << PEGASUS_STD(endl);
   
                   //listener.addAcceptor(false, portNumberHttp, false);
       Logger::put(Logger::STANDARD_LOG, System::CIMLISTENER, Logger::INFORMATION,
                           "Listening on HTTP port $0.", _portNumber);
  
     PEG_FUNC_EXIT(TRC_SERVER, METHOD_NAME);  
 } }
   }
   void CIMListenerService::runForever()
   {
           static int modulator = 0;
  
 CIMListener::~CIMListener()          if(!_dieNow)
           {
       #ifdef PEGASUS_USE_23HTTPMONITOR
       if(false == _monitor->run(100))
       {
                           modulator++;
                           if(!(modulator % 5000) )
 { {
     const char METHOD_NAME[] = "CIMListener::~CIMListener()";                                  try
                                   {
                                           //MessageQueueService::_check_idle_flag = 1;
                                           //MessageQueueService::_polling_sem.signal();
                                           MessageQueueService::get_thread_pool()->kill_idle_threads();
                                   }
                                   catch(...)
                                   {
                                   }
                           }
                   }
   /*
                   if (handleShutdownSignal)
                   {
                           Tracer::trace(TRC_SERVER, Tracer::LEVEL3,
                                   "CIMServer::runForever - signal received.  Shutting down.");
  
     PEG_FUNC_ENTER(TRC_SERVER, METHOD_NAME);                          ShutdownService::getInstance(this)->shutdown(true, 10, false);
                           handleShutdownSignal = false;
                   }
   */
      #else
      _monitor->run();
      #endif
           }
   }
  
     // Note: do not delete the acceptor because it belongs to the Monitor  void CIMListenerService::shutdown()
     // which takes care of disposing of it.  {
       PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::shutdown()");
   
       _dieNow = true;
  
     PEG_FUNC_EXIT(TRC_SERVER, METHOD_NAME);      PEG_METHOD_EXIT();
 } }
  
 void CIMListener::bind(Uint32 port)  void CIMListenerService::resume()
 { {
     const char METHOD_NAME[] = "CIMListener::bind()";      PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::resume()");
  
     PEG_FUNC_ENTER(TRC_SERVER, METHOD_NAME);      if(_acceptor!=NULL)
           _acceptor->reopenConnectionSocket();
   
       PEG_METHOD_EXIT();
   }
  
     // not the best place to build the service url, but it works for now  void CIMListenerService::stopClientConnection()
     // because the address string is accessible  mdday  {
       PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::stopClientConnection()");
  
     _acceptor->bind(port);      // tell Monitor to stop listening for client connections
       #ifdef PEGASUS_USE_23HTTPMONITOR
       _monitor->stopListeningForConnections();
       #else
       _monitor->stop();
       #endif
  
     PEG_FUNC_EXIT(TRC_SERVER, METHOD_NAME);      //
       // Wait 150 milliseconds to allow time for the Monitor to stop
       // listening for client connections.
       //
       // This wait time is the timeout value for the select() call
       // in the Monitor's run() method (currently set to 100
       // milliseconds) plus a delta of 50 milliseconds.  The reason
       // for the wait here is to make sure that the Monitor entries
       // are updated before closing the connection sockets.
       //
       pegasus_sleep(150);
   
       if(_acceptor!=NULL)
       _acceptor->closeConnectionSocket();
   
       PEG_METHOD_EXIT();
 } }
  
 void CIMListener::runForever()  
   CIMListenerIndicationDispatcher* CIMListenerService::getIndicationDispatcher() const
 { {
     //ATTN: Do not add Trace code in this method.          return _dispatcher;
     if(!_dieNow)  
         _monitor->run(100);  
 } }
   void CIMListenerService::setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher)
 void CIMListener::stopClientConnection()  
 { {
     const char METHOD_NAME[] = "CIMListener::stopClientConnection()";          _dispatcher = dispatcher;
   }
  
     PEG_FUNC_ENTER(TRC_SERVER, METHOD_NAME);  PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL CIMListenerService::_listener_routine(void *param)
   {
     CIMListenerService *svc = reinterpret_cast<CIMListenerService *>(param);
  
     _acceptor->closeConnectionSocket();          svc->init();
           while(!svc->terminated())
           {
             svc->runForever();
   }
           delete svc;
  
     PEG_FUNC_EXIT(TRC_SERVER, METHOD_NAME);          return 0;
 } }
   static struct timeval create_time = {0, 1};
   static struct timeval destroy_time = {15, 0};
   static struct timeval deadlock_time = {0, 0};
   
   /////////////////////////////////////////////////////////////////////////////
   // CIMListenerRep
   /////////////////////////////////////////////////////////////////////////////
   class CIMListenerRep
   {
   public:
           CIMListenerRep(Uint32 portNumber, SSLContext* sslContext=NULL);
     ~CIMListenerRep();
   
           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:
           Uint32                  _portNumber;
           SSLContext* _sslContext;
  
 void CIMListener::shutdown()    CIMListenerIndicationDispatcher* _dispatcher;
           ThreadPool* _thread_pool;
   };
   
   CIMListenerRep::CIMListenerRep(Uint32 portNumber, SSLContext* sslContext)
   :_portNumber(portNumber)
   ,_sslContext(sslContext)
   ,_dispatcher(new CIMListenerIndicationDispatcher())
   ,_thread_pool(NULL)
   {
   }
   CIMListenerRep::~CIMListenerRep()
 { {
     const char METHOD_NAME[] = "CIMListener::shutdown()";          // if port is alive, clean up the port
           if(_sslContext!=NULL)
                   delete _sslContext;
  
     PEG_FUNC_ENTER(TRC_SERVER, METHOD_NAME);          if(_dispatcher!=NULL)
                   delete _dispatcher;
  
     _dieNow = true;          if(_thread_pool!=NULL)
                   delete _thread_pool;
   }
  
     PEG_FUNC_EXIT(TRC_SERVER, METHOD_NAME);  Uint32 CIMListenerRep::getPortNumber() const
   {
           return _portNumber;
 } }
  
 void CIMListener::resume()  SSLContext* CIMListenerRep::getSSLContext() const
 { {
     const char METHOD_NAME[] = "CIMListener::resume()";          return _sslContext;
   }
   void CIMListenerRep::setSSLContext(SSLContext* sslContext)
   {
           if(_sslContext!=NULL)
                   delete _sslContext;
  
     PEG_FUNC_ENTER(TRC_SERVER, METHOD_NAME);          _sslContext = sslContext;
   }
   void CIMListenerRep::start()
   {
           // spawn a thread to do this
           if(_thread_pool==NULL)
           {
                   _thread_pool = new ThreadPool(0, "Listener", 0, 1,
                           create_time, destroy_time, deadlock_time);
  
     _acceptor->reopenConnectionSocket();                  CIMListenerService* svc = new CIMListenerService(_portNumber,_sslContext);
                   svc->setIndicationDispatcher(_dispatcher);
  
     PEG_FUNC_EXIT(TRC_SERVER, METHOD_NAME);                  _thread_pool->allocate_and_awaken(svc,CIMListenerService::_listener_routine);
   
                   Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
                                                 Logger::INFORMATION,
                                           "CIMListener started");
   
                   PEGASUS_STD(cerr) << "CIMlistener started" << PEGASUS_STD(endl);
           }
 } }
  
 CIMExportRequestDispatcher* CIMListener::getDispatcher()  void CIMListenerRep::stop()
 { {
     const char METHOD_NAME[] = "CIMListener::getDispatcher()";          if(_thread_pool!=NULL)
           { // stop the thread
   
                   delete _thread_pool;
   
                   Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
                                                       Logger::INFORMATION,
                                                 "CIMListener stopped");
           }
   }
  
     PEG_FUNC_ENTER(TRC_SERVER, METHOD_NAME);  Boolean CIMListenerRep::isAlive()
   {
           return (_thread_pool!=NULL)?true:false;
   }
  
     PEG_FUNC_EXIT(TRC_SERVER, METHOD_NAME);  Boolean CIMListenerRep::addConsumer(CIMIndicationConsumer* consumer)
   {
           return _dispatcher->addConsumer(consumer);
   }
   Boolean CIMListenerRep::removeConsumer(CIMIndicationConsumer* consumer)
   {
           return _dispatcher->removeConsumer(consumer);
   }
  
     return _cimExportRequestDispatcher;  /////////////////////////////////////////////////////////////////////////////
   // CIMListener
   /////////////////////////////////////////////////////////////////////////////
   CIMListener::CIMListener(Uint32 portNumber, SSLContext* sslContext)
   :_rep(new CIMListenerRep(portNumber,sslContext))
   {
   }
   CIMListener::~CIMListener()
   {
           if(_rep!=NULL)
                   delete static_cast<CIMListenerRep*>(_rep);
           _rep=NULL;
 } }
  
 Uint32 CIMListener::getOutstandingRequestCount()  Uint32 CIMListener::getPortNumber() const
 { {
     const char METHOD_NAME[] = "CIMListener::getOutstandingRequestCount()";          return static_cast<CIMListenerRep*>(_rep)->getPortNumber();
   }
  
     PEG_FUNC_ENTER(TRC_SERVER, METHOD_NAME);  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();
   }
  
     PEG_FUNC_EXIT(TRC_SERVER, METHOD_NAME);  Boolean CIMListener::isAlive()
   {
           return static_cast<CIMListenerRep*>(_rep)->isAlive();
   }
  
     return (_acceptor->getOutstandingRequestCount());  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.2  
changed lines
  Added in v.1.14

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2