(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 tony  1.8     if(_acceptor!=NULL)
254               _acceptor->closeConnectionSocket();
255 kumpf 1.1 
256 kumpf 1.4     PEG_METHOD_EXIT();
257 kumpf 1.1 }
258           
259 tony  1.8 
260           CIMListenerIndicationDispatcher* CIMListenerService::getIndicationDispatcher() const
261 kumpf 1.1 {
262 tony  1.8 	return _dispatcher;
263           }
264           void CIMListenerService::setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher)
265           {
266           	_dispatcher = dispatcher;
267 kumpf 1.1 }
268           
269 tony  1.8 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL CIMListenerService::_listener_routine(void *param)
270 kumpf 1.1 {
271 tony  1.8   CIMListenerService *svc = reinterpret_cast<CIMListenerService *>(param);
272 kumpf 1.1 
273 tony  1.8 	svc->init();
274           	while(!svc->terminated())
275           	{
276           	  svc->runForever();
277           }
278           	delete svc;
279           
280           	return 0;
281           }
282           static struct timeval create_time = {0, 1};
283           static struct timeval destroy_time = {15, 0};
284           static struct timeval deadlock_time = {0, 0};
285           
286           /////////////////////////////////////////////////////////////////////////////
287           // CIMListenerRep
288           /////////////////////////////////////////////////////////////////////////////
289           class CIMListenerRep
290           {
291           public:
292           	CIMListenerRep(Uint32 portNumber, SSLContext* sslContext=NULL);
293             ~CIMListenerRep();
294 tony  1.8 
295           	Uint32 getPortNumber() const;
296           
297           	SSLContext* getSSLContext() const;
298           	void setSSLContext(SSLContext* sslContext);
299           	
300           	void start();
301           	void stop();
302           
303           	Boolean isAlive();
304           
305           	Boolean addConsumer(CIMIndicationConsumer* consumer);
306           	Boolean removeConsumer(CIMIndicationConsumer* consumer);
307           
308           private:
309           	Uint32			_portNumber;
310           	SSLContext* _sslContext;
311           
312             CIMListenerIndicationDispatcher* _dispatcher;
313           	ThreadPool* _thread_pool;
314           };
315 tony  1.8 
316           CIMListenerRep::CIMListenerRep(Uint32 portNumber, SSLContext* sslContext)
317           :_portNumber(portNumber)
318           ,_sslContext(sslContext)
319           ,_dispatcher(new CIMListenerIndicationDispatcher())
320           ,_thread_pool(NULL)
321           {
322           }
323           CIMListenerRep::~CIMListenerRep()
324           {
325           	// if port is alive, clean up the port
326           	if(_sslContext!=NULL)
327           		delete _sslContext;
328           
329           	if(_dispatcher!=NULL)
330           		delete _dispatcher;
331           
332           	if(_thread_pool!=NULL)
333           		delete _thread_pool;
334           }
335           
336 tony  1.8 Uint32 CIMListenerRep::getPortNumber() const
337           {
338           	return _portNumber;
339           }
340 kumpf 1.1 
341 tony  1.8 SSLContext* CIMListenerRep::getSSLContext() const
342           {
343           	return _sslContext;
344 kumpf 1.1 }
345 tony  1.8 void CIMListenerRep::setSSLContext(SSLContext* sslContext)
346           {
347           	if(_sslContext!=NULL)
348           		delete _sslContext;
349 kumpf 1.1 
350 tony  1.8 	_sslContext = sslContext;
351           }
352           void CIMListenerRep::start()
353 kumpf 1.1 {
354 tony  1.8 	// spawn a thread to do this
355           	if(_thread_pool==NULL)
356           	{
357           		_thread_pool = new ThreadPool(0, "Listener", 0, 1, 
358           			create_time, destroy_time, deadlock_time);
359           
360           		CIMListenerService* svc = new CIMListenerService(_portNumber,_sslContext);
361           		svc->setIndicationDispatcher(_dispatcher);
362           
363           		_thread_pool->allocate_and_awaken(svc,CIMListenerService::_listener_routine);
364           
365           		Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
366           					      Logger::INFORMATION,
367           				        "CIMListener started");
368 kumpf 1.1 
369 tony  1.8 		PEGASUS_STD(cerr) << "CIMlistener started" << PEGASUS_STD(endl);
370           	}
371           }
372 kumpf 1.1 
373 tony  1.8 void CIMListenerRep::stop()
374           {
375           	if(_thread_pool!=NULL)
376           	{ // stop the thread
377           		
378           		delete _thread_pool;
379           		
380           		Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
381           						    Logger::INFORMATION,
382           					      "CIMListener stopped");
383           	}
384 kumpf 1.1 }
385           
386 tony  1.8 Boolean CIMListenerRep::isAlive()
387 kumpf 1.1 {
388 tony  1.8 	return (_thread_pool!=NULL)?true:false;
389           }
390 kumpf 1.1 
391 tony  1.8 Boolean CIMListenerRep::addConsumer(CIMIndicationConsumer* consumer)
392           {
393           	return _dispatcher->addConsumer(consumer);
394           }
395           Boolean CIMListenerRep::removeConsumer(CIMIndicationConsumer* consumer)
396           {
397           	return _dispatcher->removeConsumer(consumer);
398           }
399 kumpf 1.1 
400 tony  1.8 /////////////////////////////////////////////////////////////////////////////
401           // CIMListener
402           /////////////////////////////////////////////////////////////////////////////
403           CIMListener::CIMListener(Uint32 portNumber, SSLContext* sslContext)
404           :_rep(new CIMListenerRep(portNumber,sslContext))
405           {
406           }
407           CIMListener::~CIMListener()
408           {
409           	if(_rep!=NULL)
410           		delete _rep;
411           	_rep=NULL;
412           }
413           	
414           Uint32 CIMListener::getPortNumber() const
415           {
416           	return static_cast<CIMListenerRep*>(_rep)->getPortNumber();
417 kumpf 1.1 }
418           
419 tony  1.8 SSLContext* CIMListener::getSSLContext() const
420           {
421           	return static_cast<CIMListenerRep*>(_rep)->getSSLContext();
422           }
423           void CIMListener::setSSLContext(SSLContext* sslContext)
424           {
425           	static_cast<CIMListenerRep*>(_rep)->setSSLContext(sslContext);
426           }
427           void CIMListener::start()
428 kumpf 1.1 {
429 tony  1.8 	static_cast<CIMListenerRep*>(_rep)->start();
430           }
431           void CIMListener::stop()
432           {
433           	static_cast<CIMListenerRep*>(_rep)->stop();
434           }
435 kumpf 1.1 
436 tony  1.8 Boolean CIMListener::isAlive()
437           {
438           	return static_cast<CIMListenerRep*>(_rep)->isAlive();
439           }
440 kumpf 1.1 
441 tony  1.8 Boolean CIMListener::addConsumer(CIMIndicationConsumer* consumer)
442           {
443           	return static_cast<CIMListenerRep*>(_rep)->addConsumer(consumer);
444           }
445           Boolean CIMListener::removeConsumer(CIMIndicationConsumer* consumer)
446           {
447           	return static_cast<CIMListenerRep*>(_rep)->removeConsumer(consumer);
448 kumpf 1.1 }
449           
450           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2