(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 chuck    1.17   //	svc->init(); bug 1394 
318 tony     1.8  	while(!svc->terminated())
319               	{
320 dudhe.girish 1.18           #if defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU)
321                   		pthread_testcancel();
322                   	  #endif
323 tony         1.8  	  svc->runForever();
324                   }
325                   	delete svc;
326                   
327                   	return 0;
328                   }
329                   static struct timeval create_time = {0, 1};
330                   static struct timeval destroy_time = {15, 0};
331                   static struct timeval deadlock_time = {0, 0};
332                   
333                   /////////////////////////////////////////////////////////////////////////////
334                   // CIMListenerRep
335                   /////////////////////////////////////////////////////////////////////////////
336                   class CIMListenerRep
337                   {
338                   public:
339                   	CIMListenerRep(Uint32 portNumber, SSLContext* sslContext=NULL);
340                     ~CIMListenerRep();
341                   
342                   	Uint32 getPortNumber() const;
343                   
344 tony         1.8  	SSLContext* getSSLContext() const;
345                   	void setSSLContext(SSLContext* sslContext);
346                   	
347                   	void start();
348                   	void stop();
349                   
350                   	Boolean isAlive();
351                   
352                   	Boolean addConsumer(CIMIndicationConsumer* consumer);
353                   	Boolean removeConsumer(CIMIndicationConsumer* consumer);
354                   
355                   private:
356                   	Uint32			_portNumber;
357                   	SSLContext* _sslContext;
358                   
359                     CIMListenerIndicationDispatcher* _dispatcher;
360                   	ThreadPool* _thread_pool;
361                   };
362                   
363                   CIMListenerRep::CIMListenerRep(Uint32 portNumber, SSLContext* sslContext)
364                   :_portNumber(portNumber)
365 tony         1.8  ,_sslContext(sslContext)
366                   ,_dispatcher(new CIMListenerIndicationDispatcher())
367                   ,_thread_pool(NULL)
368                   {
369                   }
370                   CIMListenerRep::~CIMListenerRep()
371                   {
372                   	// if port is alive, clean up the port
373                   	if(_sslContext!=NULL)
374                   		delete _sslContext;
375                   
376                   	if(_dispatcher!=NULL)
377                   		delete _dispatcher;
378                   
379                   	if(_thread_pool!=NULL)
380                   		delete _thread_pool;
381                   }
382                   
383                   Uint32 CIMListenerRep::getPortNumber() const
384                   {
385                   	return _portNumber;
386 tony         1.8  }
387 kumpf        1.1  
388 tony         1.8  SSLContext* CIMListenerRep::getSSLContext() const
389                   {
390                   	return _sslContext;
391 kumpf        1.1  }
392 tony         1.8  void CIMListenerRep::setSSLContext(SSLContext* sslContext)
393                   {
394                   	if(_sslContext!=NULL)
395                   		delete _sslContext;
396 kumpf        1.1  
397 tony         1.8  	_sslContext = sslContext;
398                   }
399                   void CIMListenerRep::start()
400 kumpf        1.1  {
401 tony         1.8  	// spawn a thread to do this
402                   	if(_thread_pool==NULL)
403                   	{
404 chuck        1.17 		CIMListenerService* svc = new CIMListenerService(_portNumber,_sslContext);
405                   		try
406                   		{
407                   		  // Try to initialize the service (bug 1394)
408                   		  svc->setIndicationDispatcher(_dispatcher);
409                   		  svc->init(); 
410                   		}
411                   		catch(...)
412                   		{
413                   		  // Error. Exit without creating the ThreadPool, so that this listener
414                   		  // is not 'alive'
415                   		  delete svc;
416                   		  throw;
417                   		}
418                   
419 tony         1.8  		_thread_pool = new ThreadPool(0, "Listener", 0, 1, 
420                   			create_time, destroy_time, deadlock_time);
421                   
422                   		_thread_pool->allocate_and_awaken(svc,CIMListenerService::_listener_routine);
423                   
424                   		Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
425                   					      Logger::INFORMATION,
426                   				        "CIMListener started");
427 kumpf        1.1  
428 tony         1.8  		PEGASUS_STD(cerr) << "CIMlistener started" << PEGASUS_STD(endl);
429                   	}
430                   }
431 kumpf        1.1  
432 tony         1.8  void CIMListenerRep::stop()
433                   {
434                   	if(_thread_pool!=NULL)
435                   	{ // stop the thread
436                   		
437                   		delete _thread_pool;
438 chuck        1.16 		_thread_pool = NULL;
439 tony         1.8  		
440                   		Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
441                   						    Logger::INFORMATION,
442                   					      "CIMListener stopped");
443                   	}
444 kumpf        1.1  }
445                   
446 tony         1.8  Boolean CIMListenerRep::isAlive()
447 kumpf        1.1  {
448 tony         1.8  	return (_thread_pool!=NULL)?true:false;
449                   }
450 kumpf        1.1  
451 tony         1.8  Boolean CIMListenerRep::addConsumer(CIMIndicationConsumer* consumer)
452                   {
453                   	return _dispatcher->addConsumer(consumer);
454                   }
455                   Boolean CIMListenerRep::removeConsumer(CIMIndicationConsumer* consumer)
456                   {
457                   	return _dispatcher->removeConsumer(consumer);
458                   }
459 kumpf        1.1  
460 tony         1.8  /////////////////////////////////////////////////////////////////////////////
461                   // CIMListener
462                   /////////////////////////////////////////////////////////////////////////////
463                   CIMListener::CIMListener(Uint32 portNumber, SSLContext* sslContext)
464                   :_rep(new CIMListenerRep(portNumber,sslContext))
465                   {
466                   }
467                   CIMListener::~CIMListener()
468                   {
469                   	if(_rep!=NULL)
470 tony         1.9  		delete static_cast<CIMListenerRep*>(_rep);
471 tony         1.8  	_rep=NULL;
472                   }
473                   	
474                   Uint32 CIMListener::getPortNumber() const
475                   {
476                   	return static_cast<CIMListenerRep*>(_rep)->getPortNumber();
477 kumpf        1.1  }
478                   
479 tony         1.8  SSLContext* CIMListener::getSSLContext() const
480                   {
481                   	return static_cast<CIMListenerRep*>(_rep)->getSSLContext();
482                   }
483                   void CIMListener::setSSLContext(SSLContext* sslContext)
484                   {
485                   	static_cast<CIMListenerRep*>(_rep)->setSSLContext(sslContext);
486                   }
487                   void CIMListener::start()
488 kumpf        1.1  {
489 tony         1.8  	static_cast<CIMListenerRep*>(_rep)->start();
490                   }
491                   void CIMListener::stop()
492                   {
493                   	static_cast<CIMListenerRep*>(_rep)->stop();
494                   }
495 kumpf        1.1  
496 tony         1.8  Boolean CIMListener::isAlive()
497                   {
498                   	return static_cast<CIMListenerRep*>(_rep)->isAlive();
499                   }
500 kumpf        1.1  
501 tony         1.8  Boolean CIMListener::addConsumer(CIMIndicationConsumer* consumer)
502                   {
503                   	return static_cast<CIMListenerRep*>(_rep)->addConsumer(consumer);
504                   }
505                   Boolean CIMListener::removeConsumer(CIMIndicationConsumer* consumer)
506                   {
507                   	return static_cast<CIMListenerRep*>(_rep)->removeConsumer(consumer);
508 kumpf        1.1  }
509                   
510                   PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2