(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.18 and 1.40.12.1

version 1.18, 2004/05/13 14:16:42 version 1.40.12.1, 2006/07/05 19:45:12
Line 1 
Line 1 
 //%2003////////////////////////////////////////////////////////////////////////  //%2006////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development  // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
 // Company, L. P., IBM Corp., 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.; // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
 // IBM Corp.; EMC Corporation, The Open Group. // IBM Corp.; EMC Corporation, The Open Group.
   // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
   // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
   // EMC Corporation; VERITAS Software Corporation; The Open Group.
   // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
   // EMC Corporation; Symantec 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 26 
Line 32 
 // Author: Dong Xiang, EMC Corporation (xiang_dong@emc.com) // Author: Dong Xiang, EMC Corporation (xiang_dong@emc.com)
 // //
 // Modified By:   Dan Gorey (djgorey@us.ibm.com) // Modified By:   Dan Gorey (djgorey@us.ibm.com)
   //                Amit K Arora, IBM (amita@in.ibm.com) for PEP#183
   //                Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
   //                David Dillard, VERITAS Software Corp.
   //                    (david.dillard@veritas.com)
   //                Vijay Eli, IBM (vijay.eli@in.ibm.com) for bug#3425
   //                Aruran, IBM (ashanmug@in.ibm.com) for Bug# 3604
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
Line 36 
Line 48 
 #include <Pegasus/Common/Monitor.h> #include <Pegasus/Common/Monitor.h>
 #include <Pegasus/Common/HTTPAcceptor.h> #include <Pegasus/Common/HTTPAcceptor.h>
 #include <Pegasus/Common/PegasusVersion.h> #include <Pegasus/Common/PegasusVersion.h>
   #include <Pegasus/Common/MessageLoader.h>
  
 #include <Pegasus/ExportServer/CIMExportResponseEncoder.h> #include <Pegasus/ExportServer/CIMExportResponseEncoder.h>
 #include <Pegasus/ExportServer/CIMExportRequestDecoder.h> #include <Pegasus/ExportServer/CIMExportRequestDecoder.h>
Line 75 
Line 88 
  
         /** Return true if the server has shutdown, false otherwise.         /** Return true if the server has shutdown, false otherwise.
         */         */
         Boolean terminated() { return _dieNow; };          Boolean terminated() const { return _dieNow; };
  
         /** Call to resume the sever.         /** Call to resume the sever.
         */         */
Line 96 
Line 109 
          */          */
         void setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher);         void setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher);
  
           /** Returns the port number being used.
            */
           Uint32 getPortNumber() const;
   
         static PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL _listener_routine(void *param);         static PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL _listener_routine(void *param);
  
 private: private:
         Uint32                  _portNumber;         Uint32                  _portNumber;
         SSLContext* _sslContext;         SSLContext* _sslContext;
   #ifdef PEGASUS_USE_23HTTPMONITOR_CLIENT  
         Monitor*                                _monitor;         Monitor*                                _monitor;
           Mutex _monitorMutex;
   HTTPAcceptor*   _acceptor;   HTTPAcceptor*   _acceptor;
   #else  
         monitor_2*                              _monitor;  
   pegasus_acceptor*   _acceptor;  
   #endif  
  
   Boolean                                       _dieNow;   Boolean                                       _dieNow;
  
Line 144 
Line 157 
 CIMListenerService::~CIMListenerService() CIMListenerService::~CIMListenerService()
 { {
         // if port is alive, clean up the port         // if port is alive, clean up the port
         //if(_sslContext!=NULL)  
         //      delete _sslContext;         //      delete _sslContext;
  
         if(_responseEncoder!=NULL)  
                 delete _responseEncoder;                 delete _responseEncoder;
  
         if(_requestDecoder!=NULL)  
                 delete _requestDecoder;                 delete _requestDecoder;
  
         //if(_dispatcher!=NULL)  
         //      delete _dispatcher;         //      delete _dispatcher;
  
         if(_monitor!=NULL)  
                 delete _monitor;  
   
         if(_acceptor!=NULL)  
                 delete _acceptor;                 delete _acceptor;
   
       delete _monitor;
 } }
  
 void CIMListenerService::init() void CIMListenerService::init()
 { {
         PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::init");         PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::init");
  
   #ifdef PEGASUS_USE_23HTTPMONITOR_CLIENT    if(NULL == _monitor) _monitor = new Monitor();
   _monitor = new Monitor(true);  
   #else  
   _monitor = new monitor_2();  
   #endif  
  
         //_dispatcher = new CIMListenerIndicationDispatcher();         //_dispatcher = new CIMListenerIndicationDispatcher();
  
         _responseEncoder = new CIMExportResponseEncoder();    if(NULL == _responseEncoder) _responseEncoder = new CIMExportResponseEncoder();
   _requestDecoder = new CIMExportRequestDecoder(    if(NULL == _requestDecoder) _requestDecoder = new CIMExportRequestDecoder(
                 _dispatcher,                                        _dispatcher,_responseEncoder->getQueueId());
                 _responseEncoder->getQueueId());  
  
   #ifdef PEGASUS_USE_23HTTPMONITOR_CLIENT    if(NULL == _acceptor) _acceptor = new HTTPAcceptor(
   _acceptor = new HTTPAcceptor(  
                  _monitor,                  _monitor,
                  _requestDecoder,                  _requestDecoder,
                  false,                  false,
                  _portNumber,                  _portNumber,
                  _sslContext);                   _sslContext,
   #else                   false);
   _acceptor = new pegasus_acceptor(_monitor,  
                    _requestDecoder,  
                    false,  
                    _portNumber,  
                    _sslContext);  
   #endif  
  
         bind();         bind();
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
   
 void CIMListenerService::bind() void CIMListenerService::bind()
 { {
         if(_acceptor!=NULL)         if(_acceptor!=NULL)
         { // Bind to the port         { // Bind to the port
                 _acceptor->bind();                 _acceptor->bind();
  
                 PEGASUS_STD(cout) << "Listening on HTTP port " << _portNumber << PEGASUS_STD(endl);  
   
                 //listener.addAcceptor(false, portNumberHttp, false);                 //listener.addAcceptor(false, portNumberHttp, false);
     Logger::put(Logger::STANDARD_LOG, System::CIMLISTENER, Logger::INFORMATION,     Logger::put(Logger::STANDARD_LOG, System::CIMLISTENER, Logger::INFORMATION,
                         "Listening on HTTP port $0.", _portNumber);                         "Listening on HTTP port $0.", _portNumber);
  
         }         }
 } }
   
 void CIMListenerService::runForever() void CIMListenerService::runForever()
 { {
         static int modulator = 0;         static int modulator = 0;
  
         if(!_dieNow)         if(!_dieNow)
         {         {
     #ifdef PEGASUS_USE_23HTTPMONITOR_CLIENT        if(false == _monitor->run(500000))
     if(false == _monitor->run(100))  
     {     {
                         modulator++;                         modulator++;
                         if(!(modulator % 5000) )  
                         {  
                                 try                                 try
                                 {                                 {
                                         //MessageQueueService::_check_idle_flag = 1;                                         //MessageQueueService::_check_idle_flag = 1;
                                         //MessageQueueService::_polling_sem.signal();                                         //MessageQueueService::_polling_sem.signal();
                                         MessageQueueService::get_thread_pool()->kill_idle_threads();                   MessageQueueService::get_thread_pool()->cleanupIdleThreads();
                                 }                                 }
                                 catch(...)                                 catch(...)
                                 {                                 {
                                 }                                 }
                         }                         }
                 }  
 /* /*
                 if (handleShutdownSignal)                 if (handleShutdownSignal)
                 {                 {
Line 246 
Line 237 
                         handleShutdownSignal = false;                         handleShutdownSignal = false;
                 }                 }
 */ */
    #else  
    _monitor->run();  
    #endif  
         }         }
 } }
  
Line 256 
Line 244 
 { {
     PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::shutdown()");     PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::shutdown()");
  
       // 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;     _dieNow = true;
           _monitor->tickle();
       }
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
Line 276 
Line 272 
     PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::stopClientConnection()");     PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::stopClientConnection()");
  
     // tell Monitor to stop listening for client connections     // tell Monitor to stop listening for client connections
     #ifdef PEGASUS_USE_23HTTPMONITOR_CLIENT      _monitor->stopListeningForConnections(true);
     _monitor->stopListeningForConnections();  
     #else  
     _monitor->stop();  
     #endif  
  
     //     //
     // Wait 150 milliseconds to allow time for the Monitor to stop     // Wait 150 milliseconds to allow time for the Monitor to stop
Line 292 
Line 284 
     // for the wait here is to make sure that the Monitor entries     // for the wait here is to make sure that the Monitor entries
     // are updated before closing the connection sockets.     // are updated before closing the connection sockets.
     //     //
     pegasus_sleep(150);      // pegasus_sleep(150); Not needed now due to the semaphore in the Monitor
  
     if(_acceptor!=NULL)     if(_acceptor!=NULL)
     _acceptor->closeConnectionSocket();     _acceptor->closeConnectionSocket();
Line 300 
Line 292 
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
  
   Uint32 CIMListenerService::getOutstandingRequestCount()
   {
       return _acceptor->getOutstandingRequestCount();
   }
  
 CIMListenerIndicationDispatcher* CIMListenerService::getIndicationDispatcher() const CIMListenerIndicationDispatcher* CIMListenerService::getIndicationDispatcher() const
 { {
         return _dispatcher;         return _dispatcher;
 } }
   
 void CIMListenerService::setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher) void CIMListenerService::setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher)
 { {
         _dispatcher = dispatcher;         _dispatcher = dispatcher;
 } }
  
   Uint32 CIMListenerService::getPortNumber() const
   {
   
       Uint32 portNumber = _portNumber;
   
       if (( portNumber == 0 ) && ( _acceptor != 0 ))
       {
           portNumber = _acceptor->getPortNumber();
       }
   
       return(portNumber);
   }
   
 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL CIMListenerService::_listener_routine(void *param) PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL CIMListenerService::_listener_routine(void *param)
 { {
   CIMListenerService *svc = reinterpret_cast<CIMListenerService *>(param);   CIMListenerService *svc = reinterpret_cast<CIMListenerService *>(param);
  
     try {
   
   //    svc->init(); bug 1394   //    svc->init(); bug 1394
         while(!svc->terminated())         while(!svc->terminated())
         {         {
Line 322 
Line 334 
           #endif           #endif
           svc->runForever();           svc->runForever();
 } }
     } catch (...)
     {
           Tracer::trace(TRC_SERVER, Tracer::LEVEL2,
                           "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::ticle().
   
     svc->_monitorMutex.lock();
     svc->_monitorMutex.unlock();
         delete svc;         delete svc;
  
         return 0;         return 0;
 } }
 static struct timeval create_time = {0, 1};  
 static struct timeval destroy_time = {15, 0};  
 static struct timeval deadlock_time = {0, 0};  
  
 ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
 // CIMListenerRep // CIMListenerRep
Line 353 
Line 377 
         Boolean removeConsumer(CIMIndicationConsumer* consumer);         Boolean removeConsumer(CIMIndicationConsumer* consumer);
  
 private: private:
     Boolean waitForPendingRequests(Uint32 shutdownTimeout);
   
         Uint32                  _portNumber;         Uint32                  _portNumber;
         SSLContext* _sslContext;         SSLContext* _sslContext;
  
   CIMListenerIndicationDispatcher* _dispatcher;   CIMListenerIndicationDispatcher* _dispatcher;
         ThreadPool* _thread_pool;         ThreadPool* _thread_pool;
     CIMListenerService* _svc;
     Semaphore *_listener_sem;
 }; };
  
 CIMListenerRep::CIMListenerRep(Uint32 portNumber, SSLContext* sslContext) CIMListenerRep::CIMListenerRep(Uint32 portNumber, SSLContext* sslContext)
Line 365 
Line 393 
 ,_sslContext(sslContext) ,_sslContext(sslContext)
 ,_dispatcher(new CIMListenerIndicationDispatcher()) ,_dispatcher(new CIMListenerIndicationDispatcher())
 ,_thread_pool(NULL) ,_thread_pool(NULL)
   ,_svc(NULL)
   ,_listener_sem(NULL)
 { {
 } }
   
 CIMListenerRep::~CIMListenerRep() CIMListenerRep::~CIMListenerRep()
 { {
         // if port is alive, clean up the port         // if port is alive, clean up the port
         if(_sslContext!=NULL)      if (_thread_pool != 0)
                 delete _sslContext;      {
           // Block incoming export requests and unbind the port
           _svc->stopClientConnection();
  
         if(_dispatcher!=NULL)          // Wait until pending export requests in the server are done.
                 delete _dispatcher;          waitForPendingRequests(10);
  
         if(_thread_pool!=NULL)          // Shutdown the CIMListenerService
           _svc->shutdown();
       }
   
       delete _sslContext;
       delete _dispatcher;
                 delete _thread_pool;                 delete _thread_pool;
       delete _listener_sem;
   
     // don't delete _svc, this is deleted by _listener_routine
 } }
  
 Uint32 CIMListenerRep::getPortNumber() const Uint32 CIMListenerRep::getPortNumber() const
 { {
         return _portNumber;      Uint32 portNumber;
   
       if ( _svc == 0 )
       {
           portNumber = _portNumber;
       }
       else portNumber = _svc->getPortNumber();
   
       return portNumber;
 } }
  
 SSLContext* CIMListenerRep::getSSLContext() const SSLContext* CIMListenerRep::getSSLContext() const
 { {
         return _sslContext;         return _sslContext;
 } }
   
 void CIMListenerRep::setSSLContext(SSLContext* sslContext) void CIMListenerRep::setSSLContext(SSLContext* sslContext)
 { {
         if(_sslContext!=NULL)  
                 delete _sslContext;                 delete _sslContext;
   
         _sslContext = sslContext;         _sslContext = sslContext;
 } }
   
 void CIMListenerRep::start() void CIMListenerRep::start()
 { {
         // spawn a thread to do this         // spawn a thread to do this
         if(_thread_pool==NULL)      if(_thread_pool==0)
         {         {
                 CIMListenerService* svc = new CIMListenerService(_portNumber,_sslContext);          AutoPtr<CIMListenerService> svc(new CIMListenerService(_portNumber,_sslContext));
                 try  
                 {  
                   // Try to initialize the service (bug 1394)  
                   svc->setIndicationDispatcher(_dispatcher);                   svc->setIndicationDispatcher(_dispatcher);
                   svc->init();                   svc->init();
                 }  
                 catch(...)  
                 {  
                   // Error. Exit without creating the ThreadPool, so that this listener  
                   // is not 'alive'  
                   delete svc;  
                   throw;  
                 }  
   
                 _thread_pool = new ThreadPool(0, "Listener", 0, 1,  
                         create_time, destroy_time, deadlock_time);  
  
                 _thread_pool->allocate_and_awaken(svc,CIMListenerService::_listener_routine);          struct timeval deallocateWait = {15, 0};
           AutoPtr<ThreadPool> threadPool(new ThreadPool(0, "Listener", 0, 1, deallocateWait));
                 Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,          AutoPtr<Semaphore> sem(new Semaphore(0));
                                               Logger::INFORMATION,          if (threadPool->allocate_and_awaken(svc.get(), CIMListenerService::_listener_routine, sem.get()) != PEGASUS_THREAD_OK)
           {
               Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
                           "Not enough threads to start CIMListernerService.");
   
               Tracer::trace(TRC_SERVER, Tracer::LEVEL2,
                           "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");                                         "CIMListener started");
  
                 PEGASUS_STD(cerr) << "CIMlistener started" << PEGASUS_STD(endl);          _svc = svc.release();
           _thread_pool = threadPool.release();
           _listener_sem = sem.release();
         }         }
 } }
  
 void CIMListenerRep::stop() void CIMListenerRep::stop()
 { {
         if(_thread_pool!=NULL)         if(_thread_pool!=NULL)
         { // stop the thread    {
       //
       // 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);
   
       // 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.
       try
       {
         _listener_sem->time_wait(3000);
       }
       catch (const TimeOut &)
       {
         // 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;                 delete _thread_pool;
                 _thread_pool = NULL;                 _thread_pool = NULL;
  
Line 457 
Line 536 
         return _dispatcher->removeConsumer(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)
         pegasus_sleep(100);
       else
         return true;
     }
   
     return false;
   }
   
 ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
 // CIMListener // CIMListener
 ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
Line 493 
Line 589 
         static_cast<CIMListenerRep*>(_rep)->stop();         static_cast<CIMListenerRep*>(_rep)->stop();
 } }
  
 Boolean CIMListener::isAlive()  Boolean CIMListener::isAlive() const
 { {
         return static_cast<CIMListenerRep*>(_rep)->isAlive();         return static_cast<CIMListenerRep*>(_rep)->isAlive();
 } }


Legend:
Removed from v.1.18  
changed lines
  Added in v.1.40.12.1

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2