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

  1 kumpf 1.1 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3 kumpf 1.3 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4 kumpf 1.1 // The Open Group, Tivoli Systems
  5           //
  6           // Permission is hereby granted, free of charge, to any person obtaining a copy
  7           // of this software and associated documentation files (the "Software"), to
  8           // deal in the Software without restriction, including without limitation the
  9           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10           // sell copies of the Software, and to permit persons to whom the Software is
 11           // furnished to do so, subject to the following conditions:
 12 kumpf 1.3 // 
 13 kumpf 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14           // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 17           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 18           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 19           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21           //
 22           //==============================================================================
 23           //
 24 tony  1.8 // Author: Dong Xiang, EMC Corporation (xiang_dong@emc.com)
 25 kumpf 1.1 //
 26           // Modified By:
 27           //
 28           //%/////////////////////////////////////////////////////////////////////////////
 29           
 30 tony  1.8 #include "CIMListener.h"
 31 kumpf 1.1 
 32 tony  1.8 #include <Pegasus/Common/Exception.h>
 33           #include <Pegasus/Common/SSLContext.h>
 34           #include <Pegasus/Common/Monitor.h>
 35 kumpf 1.1 #include <Pegasus/Common/HTTPAcceptor.h>
 36 kumpf 1.11 #include <Pegasus/Common/PegasusVersion.h>
 37 kumpf 1.2  
 38 kumpf 1.1  #include <Pegasus/ExportServer/CIMExportResponseEncoder.h>
 39            #include <Pegasus/ExportServer/CIMExportRequestDecoder.h>
 40            
 41 tony  1.8  #include <Pegasus/Consumer/CIMIndicationConsumer.h>
 42            #include <Pegasus/Listener/CIMListenerIndicationDispatcher.h>
 43            
 44            PEGASUS_NAMESPACE_BEGIN
 45            /////////////////////////////////////////////////////////////////////////////
 46            // CIMListenerService
 47            /////////////////////////////////////////////////////////////////////////////
 48            class CIMListenerService
 49            {
 50            public:
 51            	CIMListenerService(Uint32 portNumber, SSLContext* sslContext=NULL);
 52            	CIMListenerService(CIMListenerService& svc);
 53              ~CIMListenerService();
 54            
 55            	void				init();
 56            	/** bind to the port
 57            	*/
 58            	void				bind();
 59            	/** runForever Main runloop for the server.
 60            	*/
 61            	void runForever();
 62 tony  1.8  	
 63            	/** Call to gracefully shutdown the server.  The server connection socket
 64            	will be closed to disable new connections from clients.
 65            	*/
 66            	void stopClientConnection();
 67            	
 68            	/** Call to gracefully shutdown the server.  It is called when the server
 69            	has been stopped and is ready to be shutdown.  Next time runForever()
 70            	is called, the server shuts down.
 71            	*/
 72            	void shutdown();
 73            	
 74            	/** Return true if the server has shutdown, false otherwise.
 75            	*/
 76            	Boolean terminated() { return _dieNow; };
 77            	
 78            	/** Call to resume the sever.
 79            	*/
 80            	void resume();
 81            	
 82            	/** Call to set the CIMServer state.  Also inform the appropriate
 83 tony  1.8  	message queues about the current state of the CIMServer.
 84            	*/
 85            	void setState(Uint32 state);
 86            	
 87            	Uint32 getOutstandingRequestCount();
 88            
 89            	/** Returns the indication listener dispatcher
 90            	 */
 91            	CIMListenerIndicationDispatcher* getIndicationDispatcher() const;
 92            
 93              /** Returns the indication listener dispatcher
 94            	 */
 95            	void setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher);
 96            
 97            	static PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL _listener_routine(void *param);
 98            
 99            private:
100            	Uint32			_portNumber;
101            	SSLContext* _sslContext;
102            
103            	Monitor*				_monitor;
104 tony  1.8    HTTPAcceptor*   _acceptor;
105            	Boolean					_dieNow;
106            
107              CIMListenerIndicationDispatcher* _dispatcher;
108            
109              CIMExportResponseEncoder* _responseEncoder;
110              CIMExportRequestDecoder*  _requestDecoder;
111            
112            };
113            
114            CIMListenerService::CIMListenerService(Uint32 portNumber, SSLContext* sslContext)
115            :_portNumber(portNumber)
116            ,_sslContext(sslContext)
117            ,_monitor(NULL)
118            ,_acceptor(NULL)
119            ,_dieNow(false)
120            ,_dispatcher(NULL)
121            ,_responseEncoder(NULL)
122            ,_requestDecoder(NULL)
123            {
124            }
125 tony  1.8  
126            CIMListenerService::CIMListenerService(CIMListenerService& svc)
127            :_portNumber(svc._portNumber)
128            ,_sslContext(svc._sslContext)
129            ,_monitor(NULL)
130            ,_acceptor(NULL)
131            ,_dieNow(svc._dieNow)
132            ,_dispatcher(NULL)
133            ,_responseEncoder(NULL)
134            ,_requestDecoder(NULL)
135            {
136            }
137            CIMListenerService::~CIMListenerService()
138            {
139            	// if port is alive, clean up the port
140            	//if(_sslContext!=NULL)
141            	//	delete _sslContext;
142            
143            	if(_responseEncoder!=NULL)
144            		delete _responseEncoder;
145            
146 tony  1.8  	if(_requestDecoder!=NULL)
147            		delete _requestDecoder;
148 kumpf 1.1  
149 tony  1.8  	//if(_dispatcher!=NULL)
150            	//	delete _dispatcher;
151 kumpf 1.1  
152 tony  1.8  	if(_monitor!=NULL)
153            		delete _monitor;
154 kumpf 1.1  
155 tony  1.8  	if(_acceptor!=NULL)
156            		delete _acceptor;
157            }
158 kumpf 1.1  
159 tony  1.8  void CIMListenerService::init()
160 kumpf 1.1  {
161 tony  1.8  	PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::init");
162 kumpf 1.1  
163 tony  1.8    _monitor = new Monitor(true);
164            	//_dispatcher = new CIMListenerIndicationDispatcher();
165 kumpf 1.1  
166 tony  1.8  	_responseEncoder = new CIMExportResponseEncoder();
167              _requestDecoder = new CIMExportRequestDecoder(
168            		_dispatcher,
169            		_responseEncoder->getQueueId());
170            
171            	_acceptor = new HTTPAcceptor(
172            		 _monitor, 
173            		 _requestDecoder, 
174            		 false, 
175            		 _portNumber, 
176            		 _sslContext);
177 kumpf 1.1  
178 tony  1.8  	bind();
179 kumpf 1.1  
180 tony  1.8      PEG_METHOD_EXIT();
181            }
182            void CIMListenerService::bind()
183            {
184            	if(_acceptor!=NULL)
185            	{ // Bind to the port
186            		_acceptor->bind();
187            
188            		PEGASUS_STD(cout) << "Listening on HTTP port " << _portNumber << PEGASUS_STD(endl);
189            		
190            		//listener.addAcceptor(false, portNumberHttp, false);
191                Logger::put(Logger::STANDARD_LOG, System::CIMLISTENER, Logger::INFORMATION,
192                                    "Listening on HTTP port $0.", _portNumber);
193 kumpf 1.1  
194 tony  1.8  	}
195            }
196            void CIMListenerService::runForever()
197            {
198            	static int modulator = 0;
199 kumpf 1.1  
200 tony  1.8  	if(!_dieNow)
201            	{
202            		if(false == _monitor->run(100))
203            		{
204            			modulator++;
205            			if(!(modulator % 5000) )
206            			{
207            				try 
208            				{
209            					//MessageQueueService::_check_idle_flag = 1;
210            					//MessageQueueService::_polling_sem.signal();
211            					_monitor->kill_idle_threads();
212            				}
213            				catch(...)
214            				{
215            				}
216            			}	
217            		}
218            /*
219            		if (handleShutdownSignal)
220            		{
221 tony  1.8  			Tracer::trace(TRC_SERVER, Tracer::LEVEL3,
222            				"CIMServer::runForever - signal received.  Shutting down.");
223            
224            			ShutdownService::getInstance(this)->shutdown(true, 10, false);
225            			handleShutdownSignal = false;
226            		}
227            */
228            	} 
229            }
230 kumpf 1.1  
231 tony  1.8  void CIMListenerService::shutdown()
232            {
233                PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::shutdown()");
234 kumpf 1.1  
235 tony  1.8      _dieNow = true;
236 kumpf 1.1  
237 kumpf 1.4      PEG_METHOD_EXIT();
238 kumpf 1.1  }
239            
240 tony  1.8  void CIMListenerService::resume()
241 kumpf 1.1  {
242 tony  1.8      PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::resume()");
243 kumpf 1.1  
244 tony  1.8      if(_acceptor!=NULL)
245                    _acceptor->reopenConnectionSocket();
246 kumpf 1.1  
247 kumpf 1.4      PEG_METHOD_EXIT();
248 kumpf 1.1  }
249            
250 tony  1.8  void CIMListenerService::stopClientConnection()
251 kumpf 1.1  {
252 tony  1.8      PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::stopClientConnection()");
253 kumpf 1.1  
254 kumpf 1.10     // tell Monitor to stop listening for client connections
255                _monitor->stopListeningForConnections();
256            
257                //
258                // Wait 150 milliseconds to allow time for the Monitor to stop
259                // listening for client connections.
260                //
261                // This wait time is the timeout value for the select() call
262                // in the Monitor's run() method (currently set to 100
263                // milliseconds) plus a delta of 50 milliseconds.  The reason
264                // for the wait here is to make sure that the Monitor entries
265                // are updated before closing the connection sockets.
266                //
267                pegasus_sleep(150);
268            
269 tony  1.8      if(_acceptor!=NULL)
270                _acceptor->closeConnectionSocket();
271 kumpf 1.1  
272 kumpf 1.4      PEG_METHOD_EXIT();
273 kumpf 1.1  }
274            
275 tony  1.8  
276            CIMListenerIndicationDispatcher* CIMListenerService::getIndicationDispatcher() const
277 kumpf 1.1  {
278 tony  1.8  	return _dispatcher;
279            }
280            void CIMListenerService::setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher)
281            {
282            	_dispatcher = dispatcher;
283 kumpf 1.1  }
284            
285 tony  1.8  PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL CIMListenerService::_listener_routine(void *param)
286 kumpf 1.1  {
287 tony  1.8    CIMListenerService *svc = reinterpret_cast<CIMListenerService *>(param);
288 kumpf 1.1  
289 tony  1.8  	svc->init();
290            	while(!svc->terminated())
291            	{
292            	  svc->runForever();
293            }
294            	delete svc;
295            
296            	return 0;
297            }
298            static struct timeval create_time = {0, 1};
299            static struct timeval destroy_time = {15, 0};
300            static struct timeval deadlock_time = {0, 0};
301            
302            /////////////////////////////////////////////////////////////////////////////
303            // CIMListenerRep
304            /////////////////////////////////////////////////////////////////////////////
305            class CIMListenerRep
306            {
307            public:
308            	CIMListenerRep(Uint32 portNumber, SSLContext* sslContext=NULL);
309              ~CIMListenerRep();
310 tony  1.8  
311            	Uint32 getPortNumber() const;
312            
313            	SSLContext* getSSLContext() const;
314            	void setSSLContext(SSLContext* sslContext);
315            	
316            	void start();
317            	void stop();
318            
319            	Boolean isAlive();
320            
321            	Boolean addConsumer(CIMIndicationConsumer* consumer);
322            	Boolean removeConsumer(CIMIndicationConsumer* consumer);
323            
324            private:
325            	Uint32			_portNumber;
326            	SSLContext* _sslContext;
327            
328              CIMListenerIndicationDispatcher* _dispatcher;
329            	ThreadPool* _thread_pool;
330            };
331 tony  1.8  
332            CIMListenerRep::CIMListenerRep(Uint32 portNumber, SSLContext* sslContext)
333            :_portNumber(portNumber)
334            ,_sslContext(sslContext)
335            ,_dispatcher(new CIMListenerIndicationDispatcher())
336            ,_thread_pool(NULL)
337            {
338            }
339            CIMListenerRep::~CIMListenerRep()
340            {
341            	// if port is alive, clean up the port
342            	if(_sslContext!=NULL)
343            		delete _sslContext;
344            
345            	if(_dispatcher!=NULL)
346            		delete _dispatcher;
347            
348            	if(_thread_pool!=NULL)
349            		delete _thread_pool;
350            }
351            
352 tony  1.8  Uint32 CIMListenerRep::getPortNumber() const
353            {
354            	return _portNumber;
355            }
356 kumpf 1.1  
357 tony  1.8  SSLContext* CIMListenerRep::getSSLContext() const
358            {
359            	return _sslContext;
360 kumpf 1.1  }
361 tony  1.8  void CIMListenerRep::setSSLContext(SSLContext* sslContext)
362            {
363            	if(_sslContext!=NULL)
364            		delete _sslContext;
365 kumpf 1.1  
366 tony  1.8  	_sslContext = sslContext;
367            }
368            void CIMListenerRep::start()
369 kumpf 1.1  {
370 tony  1.8  	// spawn a thread to do this
371            	if(_thread_pool==NULL)
372            	{
373            		_thread_pool = new ThreadPool(0, "Listener", 0, 1, 
374            			create_time, destroy_time, deadlock_time);
375            
376            		CIMListenerService* svc = new CIMListenerService(_portNumber,_sslContext);
377            		svc->setIndicationDispatcher(_dispatcher);
378            
379            		_thread_pool->allocate_and_awaken(svc,CIMListenerService::_listener_routine);
380            
381            		Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
382            					      Logger::INFORMATION,
383            				        "CIMListener started");
384 kumpf 1.1  
385 tony  1.8  		PEGASUS_STD(cerr) << "CIMlistener started" << PEGASUS_STD(endl);
386            	}
387            }
388 kumpf 1.1  
389 tony  1.8  void CIMListenerRep::stop()
390            {
391            	if(_thread_pool!=NULL)
392            	{ // stop the thread
393            		
394            		delete _thread_pool;
395            		
396            		Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
397            						    Logger::INFORMATION,
398            					      "CIMListener stopped");
399            	}
400 kumpf 1.1  }
401            
402 tony  1.8  Boolean CIMListenerRep::isAlive()
403 kumpf 1.1  {
404 tony  1.8  	return (_thread_pool!=NULL)?true:false;
405            }
406 kumpf 1.1  
407 tony  1.8  Boolean CIMListenerRep::addConsumer(CIMIndicationConsumer* consumer)
408            {
409            	return _dispatcher->addConsumer(consumer);
410            }
411            Boolean CIMListenerRep::removeConsumer(CIMIndicationConsumer* consumer)
412            {
413            	return _dispatcher->removeConsumer(consumer);
414            }
415 kumpf 1.1  
416 tony  1.8  /////////////////////////////////////////////////////////////////////////////
417            // CIMListener
418            /////////////////////////////////////////////////////////////////////////////
419            CIMListener::CIMListener(Uint32 portNumber, SSLContext* sslContext)
420            :_rep(new CIMListenerRep(portNumber,sslContext))
421            {
422            }
423            CIMListener::~CIMListener()
424            {
425            	if(_rep!=NULL)
426 tony  1.9  		delete static_cast<CIMListenerRep*>(_rep);
427 tony  1.8  	_rep=NULL;
428            }
429            	
430            Uint32 CIMListener::getPortNumber() const
431            {
432            	return static_cast<CIMListenerRep*>(_rep)->getPortNumber();
433 kumpf 1.1  }
434            
435 tony  1.8  SSLContext* CIMListener::getSSLContext() const
436            {
437            	return static_cast<CIMListenerRep*>(_rep)->getSSLContext();
438            }
439            void CIMListener::setSSLContext(SSLContext* sslContext)
440            {
441            	static_cast<CIMListenerRep*>(_rep)->setSSLContext(sslContext);
442            }
443            void CIMListener::start()
444 kumpf 1.1  {
445 tony  1.8  	static_cast<CIMListenerRep*>(_rep)->start();
446            }
447            void CIMListener::stop()
448            {
449            	static_cast<CIMListenerRep*>(_rep)->stop();
450            }
451 kumpf 1.1  
452 tony  1.8  Boolean CIMListener::isAlive()
453            {
454            	return static_cast<CIMListenerRep*>(_rep)->isAlive();
455            }
456 kumpf 1.1  
457 tony  1.8  Boolean CIMListener::addConsumer(CIMIndicationConsumer* consumer)
458            {
459            	return static_cast<CIMListenerRep*>(_rep)->addConsumer(consumer);
460            }
461            Boolean CIMListener::removeConsumer(CIMIndicationConsumer* consumer)
462            {
463            	return static_cast<CIMListenerRep*>(_rep)->removeConsumer(consumer);
464 kumpf 1.1  }
465            
466            PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2