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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2