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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2