(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 kumpf    1.19 		 _sslContext,
190                                false);
191 dj.gorey 1.14   #else
192                 _acceptor = new pegasus_acceptor(_monitor,
193               		   _requestDecoder,
194               		   false,
195               		   _portNumber,
196               		   _sslContext);
197                 #endif
198 kumpf    1.1  
199 tony     1.8  	bind();
200 kumpf    1.1  
201 tony     1.8      PEG_METHOD_EXIT();
202               }
203               void CIMListenerService::bind()
204               {
205               	if(_acceptor!=NULL)
206               	{ // Bind to the port
207               		_acceptor->bind();
208               
209               		PEGASUS_STD(cout) << "Listening on HTTP port " << _portNumber << PEGASUS_STD(endl);
210               		
211               		//listener.addAcceptor(false, portNumberHttp, false);
212                   Logger::put(Logger::STANDARD_LOG, System::CIMLISTENER, Logger::INFORMATION,
213                                       "Listening on HTTP port $0.", _portNumber);
214 kumpf    1.1  
215 tony     1.8  	}
216               }
217               void CIMListenerService::runForever()
218               {
219               	static int modulator = 0;
220 kumpf    1.1  
221 tony     1.8  	if(!_dieNow)
222               	{
223 dj.gorey 1.15     #ifdef PEGASUS_USE_23HTTPMONITOR_CLIENT
224 dj.gorey 1.14     if(false == _monitor->run(100))
225                   {
226 tony     1.8  			modulator++;
227               			if(!(modulator % 5000) )
228               			{
229               				try 
230               				{
231               					//MessageQueueService::_check_idle_flag = 1;
232               					//MessageQueueService::_polling_sem.signal();
233 kumpf    1.13                                         MessageQueueService::get_thread_pool()->kill_idle_threads();
234 tony     1.8  				}
235               				catch(...)
236               				{
237               				}
238               			}	
239               		}
240               /*
241               		if (handleShutdownSignal)
242               		{
243               			Tracer::trace(TRC_SERVER, Tracer::LEVEL3,
244               				"CIMServer::runForever - signal received.  Shutting down.");
245               
246               			ShutdownService::getInstance(this)->shutdown(true, 10, false);
247               			handleShutdownSignal = false;
248               		}
249               */
250 dj.gorey 1.14    #else
251                  _monitor->run();
252                  #endif
253               	}
254 tony     1.8  }
255 kumpf    1.1  
256 tony     1.8  void CIMListenerService::shutdown()
257               {
258                   PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::shutdown()");
259 kumpf    1.1  
260 tony     1.8      _dieNow = true;
261 kumpf    1.1  
262 kumpf    1.4      PEG_METHOD_EXIT();
263 kumpf    1.1  }
264               
265 tony     1.8  void CIMListenerService::resume()
266 kumpf    1.1  {
267 tony     1.8      PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::resume()");
268 kumpf    1.1  
269 tony     1.8      if(_acceptor!=NULL)
270                       _acceptor->reopenConnectionSocket();
271 kumpf    1.1  
272 kumpf    1.4      PEG_METHOD_EXIT();
273 kumpf    1.1  }
274               
275 tony     1.8  void CIMListenerService::stopClientConnection()
276 kumpf    1.1  {
277 tony     1.8      PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::stopClientConnection()");
278 kumpf    1.1  
279 kumpf    1.10     // tell Monitor to stop listening for client connections
280 dj.gorey 1.15     #ifdef PEGASUS_USE_23HTTPMONITOR_CLIENT
281 kumpf    1.10     _monitor->stopListeningForConnections();
282 dj.gorey 1.14     #else
283                   _monitor->stop();
284                   #endif
285 kumpf    1.10 
286                   //
287                   // Wait 150 milliseconds to allow time for the Monitor to stop
288                   // listening for client connections.
289                   //
290                   // This wait time is the timeout value for the select() call
291                   // in the Monitor's run() method (currently set to 100
292                   // milliseconds) plus a delta of 50 milliseconds.  The reason
293                   // for the wait here is to make sure that the Monitor entries
294                   // are updated before closing the connection sockets.
295                   //
296                   pegasus_sleep(150);
297               
298 tony     1.8      if(_acceptor!=NULL)
299                   _acceptor->closeConnectionSocket();
300 kumpf    1.1  
301 kumpf    1.4      PEG_METHOD_EXIT();
302 kumpf    1.1  }
303               
304 tony     1.8  
305               CIMListenerIndicationDispatcher* CIMListenerService::getIndicationDispatcher() const
306 kumpf    1.1  {
307 tony     1.8  	return _dispatcher;
308               }
309               void CIMListenerService::setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher)
310               {
311               	_dispatcher = dispatcher;
312 kumpf    1.1  }
313               
314 tony     1.8  PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL CIMListenerService::_listener_routine(void *param)
315 kumpf    1.1  {
316 tony     1.8    CIMListenerService *svc = reinterpret_cast<CIMListenerService *>(param);
317 kumpf    1.1  
318 chuck    1.17   //	svc->init(); bug 1394 
319 tony     1.8  	while(!svc->terminated())
320               	{
321 dudhe.girish 1.18           #if defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU)
322                   		pthread_testcancel();
323                   	  #endif
324 tony         1.8  	  svc->runForever();
325                   }
326                   	delete svc;
327                   
328                   	return 0;
329                   }
330                   static struct timeval create_time = {0, 1};
331                   static struct timeval destroy_time = {15, 0};
332                   static struct timeval deadlock_time = {0, 0};
333                   
334                   /////////////////////////////////////////////////////////////////////////////
335                   // CIMListenerRep
336                   /////////////////////////////////////////////////////////////////////////////
337                   class CIMListenerRep
338                   {
339                   public:
340                   	CIMListenerRep(Uint32 portNumber, SSLContext* sslContext=NULL);
341                     ~CIMListenerRep();
342                   
343                   	Uint32 getPortNumber() const;
344                   
345 tony         1.8  	SSLContext* getSSLContext() const;
346                   	void setSSLContext(SSLContext* sslContext);
347                   	
348                   	void start();
349                   	void stop();
350                   
351                   	Boolean isAlive();
352                   
353                   	Boolean addConsumer(CIMIndicationConsumer* consumer);
354                   	Boolean removeConsumer(CIMIndicationConsumer* consumer);
355                   
356                   private:
357                   	Uint32			_portNumber;
358                   	SSLContext* _sslContext;
359                   
360                     CIMListenerIndicationDispatcher* _dispatcher;
361                   	ThreadPool* _thread_pool;
362                   };
363                   
364                   CIMListenerRep::CIMListenerRep(Uint32 portNumber, SSLContext* sslContext)
365                   :_portNumber(portNumber)
366 tony         1.8  ,_sslContext(sslContext)
367                   ,_dispatcher(new CIMListenerIndicationDispatcher())
368                   ,_thread_pool(NULL)
369                   {
370                   }
371                   CIMListenerRep::~CIMListenerRep()
372                   {
373                   	// if port is alive, clean up the port
374                   	if(_sslContext!=NULL)
375                   		delete _sslContext;
376                   
377                   	if(_dispatcher!=NULL)
378                   		delete _dispatcher;
379                   
380                   	if(_thread_pool!=NULL)
381                   		delete _thread_pool;
382                   }
383                   
384                   Uint32 CIMListenerRep::getPortNumber() const
385                   {
386                   	return _portNumber;
387 tony         1.8  }
388 kumpf        1.1  
389 tony         1.8  SSLContext* CIMListenerRep::getSSLContext() const
390                   {
391                   	return _sslContext;
392 kumpf        1.1  }
393 tony         1.8  void CIMListenerRep::setSSLContext(SSLContext* sslContext)
394                   {
395                   	if(_sslContext!=NULL)
396                   		delete _sslContext;
397 kumpf        1.1  
398 tony         1.8  	_sslContext = sslContext;
399                   }
400                   void CIMListenerRep::start()
401 kumpf        1.1  {
402 tony         1.8  	// spawn a thread to do this
403                   	if(_thread_pool==NULL)
404                   	{
405 chuck        1.17 		CIMListenerService* svc = new CIMListenerService(_portNumber,_sslContext);
406                   		try
407                   		{
408                   		  // Try to initialize the service (bug 1394)
409                   		  svc->setIndicationDispatcher(_dispatcher);
410                   		  svc->init(); 
411                   		}
412                   		catch(...)
413                   		{
414                   		  // Error. Exit without creating the ThreadPool, so that this listener
415                   		  // is not 'alive'
416                   		  delete svc;
417                   		  throw;
418                   		}
419                   
420 tony         1.8  		_thread_pool = new ThreadPool(0, "Listener", 0, 1, 
421                   			create_time, destroy_time, deadlock_time);
422                   
423                   		_thread_pool->allocate_and_awaken(svc,CIMListenerService::_listener_routine);
424                   
425                   		Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
426                   					      Logger::INFORMATION,
427                   				        "CIMListener started");
428 kumpf        1.1  
429 tony         1.8  		PEGASUS_STD(cerr) << "CIMlistener started" << PEGASUS_STD(endl);
430                   	}
431                   }
432 kumpf        1.1  
433 tony         1.8  void CIMListenerRep::stop()
434                   {
435                   	if(_thread_pool!=NULL)
436                   	{ // stop the thread
437                   		
438                   		delete _thread_pool;
439 chuck        1.16 		_thread_pool = NULL;
440 tony         1.8  		
441                   		Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
442                   						    Logger::INFORMATION,
443                   					      "CIMListener stopped");
444                   	}
445 kumpf        1.1  }
446                   
447 tony         1.8  Boolean CIMListenerRep::isAlive()
448 kumpf        1.1  {
449 tony         1.8  	return (_thread_pool!=NULL)?true:false;
450                   }
451 kumpf        1.1  
452 tony         1.8  Boolean CIMListenerRep::addConsumer(CIMIndicationConsumer* consumer)
453                   {
454                   	return _dispatcher->addConsumer(consumer);
455                   }
456                   Boolean CIMListenerRep::removeConsumer(CIMIndicationConsumer* consumer)
457                   {
458                   	return _dispatcher->removeConsumer(consumer);
459                   }
460 kumpf        1.1  
461 tony         1.8  /////////////////////////////////////////////////////////////////////////////
462                   // CIMListener
463                   /////////////////////////////////////////////////////////////////////////////
464                   CIMListener::CIMListener(Uint32 portNumber, SSLContext* sslContext)
465                   :_rep(new CIMListenerRep(portNumber,sslContext))
466                   {
467                   }
468                   CIMListener::~CIMListener()
469                   {
470                   	if(_rep!=NULL)
471 tony         1.9  		delete static_cast<CIMListenerRep*>(_rep);
472 tony         1.8  	_rep=NULL;
473                   }
474                   	
475                   Uint32 CIMListener::getPortNumber() const
476                   {
477                   	return static_cast<CIMListenerRep*>(_rep)->getPortNumber();
478 kumpf        1.1  }
479                   
480 tony         1.8  SSLContext* CIMListener::getSSLContext() const
481                   {
482                   	return static_cast<CIMListenerRep*>(_rep)->getSSLContext();
483                   }
484                   void CIMListener::setSSLContext(SSLContext* sslContext)
485                   {
486                   	static_cast<CIMListenerRep*>(_rep)->setSSLContext(sslContext);
487                   }
488                   void CIMListener::start()
489 kumpf        1.1  {
490 tony         1.8  	static_cast<CIMListenerRep*>(_rep)->start();
491                   }
492                   void CIMListener::stop()
493                   {
494                   	static_cast<CIMListenerRep*>(_rep)->stop();
495                   }
496 kumpf        1.1  
497 tony         1.8  Boolean CIMListener::isAlive()
498                   {
499                   	return static_cast<CIMListenerRep*>(_rep)->isAlive();
500                   }
501 kumpf        1.1  
502 tony         1.8  Boolean CIMListener::addConsumer(CIMIndicationConsumer* consumer)
503                   {
504                   	return static_cast<CIMListenerRep*>(_rep)->addConsumer(consumer);
505                   }
506                   Boolean CIMListener::removeConsumer(CIMIndicationConsumer* consumer)
507                   {
508                   	return static_cast<CIMListenerRep*>(_rep)->removeConsumer(consumer);
509 kumpf        1.1  }
510                   
511                   PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2