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

  1 karl  1.40 //%2006////////////////////////////////////////////////////////////////////////
  2 kumpf 1.1  //
  3 karl  1.25 // 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 karl  1.12 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.25 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.28 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.40 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 kumpf 1.1  //
 14            // Permission is hereby granted, free of charge, to any person obtaining a copy
 15            // of this software and associated documentation files (the "Software"), to
 16            // deal in the Software without restriction, including without limitation the
 17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18            // sell copies of the Software, and to permit persons to whom the Software is
 19            // furnished to do so, subject to the following conditions:
 20 karl  1.40 // 
 21 kumpf 1.1  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22            // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24            // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29            //
 30            //==============================================================================
 31            //
 32            //%/////////////////////////////////////////////////////////////////////////////
 33            
 34 tony  1.8  #include "CIMListener.h"
 35 kumpf 1.1  
 36 tony  1.8  #include <Pegasus/Common/Exception.h>
 37            #include <Pegasus/Common/SSLContext.h>
 38            #include <Pegasus/Common/Monitor.h>
 39 kumpf 1.1  #include <Pegasus/Common/HTTPAcceptor.h>
 40 kumpf 1.11 #include <Pegasus/Common/PegasusVersion.h>
 41 konrad.r 1.38 #include <Pegasus/Common/MessageLoader.h>
 42 kumpf    1.2  
 43 kumpf    1.1  #include <Pegasus/ExportServer/CIMExportResponseEncoder.h>
 44               #include <Pegasus/ExportServer/CIMExportRequestDecoder.h>
 45               
 46 tony     1.8  #include <Pegasus/Consumer/CIMIndicationConsumer.h>
 47               #include <Pegasus/Listener/CIMListenerIndicationDispatcher.h>
 48               
 49               PEGASUS_NAMESPACE_BEGIN
 50               /////////////////////////////////////////////////////////////////////////////
 51               // CIMListenerService
 52               /////////////////////////////////////////////////////////////////////////////
 53               class CIMListenerService
 54               {
 55               public:
 56               	CIMListenerService(Uint32 portNumber, SSLContext* sslContext=NULL);
 57               	CIMListenerService(CIMListenerService& svc);
 58                 ~CIMListenerService();
 59               
 60               	void				init();
 61               	/** bind to the port
 62               	*/
 63               	void				bind();
 64               	/** runForever Main runloop for the server.
 65               	*/
 66               	void runForever();
 67 david.dillard 1.31 
 68 tony          1.8  	/** Call to gracefully shutdown the server.  The server connection socket
 69                    	will be closed to disable new connections from clients.
 70                    	*/
 71                    	void stopClientConnection();
 72 david.dillard 1.31 
 73 tony          1.8  	/** Call to gracefully shutdown the server.  It is called when the server
 74                    	has been stopped and is ready to be shutdown.  Next time runForever()
 75                    	is called, the server shuts down.
 76                    	*/
 77                    	void shutdown();
 78 david.dillard 1.31 
 79 tony          1.8  	/** Return true if the server has shutdown, false otherwise.
 80                    	*/
 81 david.dillard 1.34 	Boolean terminated() const { return _dieNow; };
 82 david.dillard 1.31 
 83 tony          1.8  	/** Call to resume the sever.
 84                    	*/
 85                    	void resume();
 86 david.dillard 1.31 
 87 tony          1.8  	/** Call to set the CIMServer state.  Also inform the appropriate
 88                    	message queues about the current state of the CIMServer.
 89                    	*/
 90                    	void setState(Uint32 state);
 91 david.dillard 1.31 
 92 tony          1.8  	Uint32 getOutstandingRequestCount();
 93                    
 94                    	/** Returns the indication listener dispatcher
 95                    	 */
 96                    	CIMListenerIndicationDispatcher* getIndicationDispatcher() const;
 97                    
 98 david.dillard 1.34 	/** Returns the indication listener dispatcher
 99 tony          1.8  	 */
100                    	void setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher);
101                    
102 david.dillard 1.34 	/** Returns the port number being used.
103                    	 */
104                    	Uint32 getPortNumber() const;
105                    
106 tony          1.8  	static PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL _listener_routine(void *param);
107                    
108                    private:
109 david.dillard 1.34 	Uint32 _portNumber;
110 tony          1.8  	SSLContext* _sslContext;
111 david.dillard 1.34 	Monitor* _monitor;
112                    	HTTPAcceptor* _acceptor;
113 dj.gorey      1.14 
114                      Boolean					_dieNow;
115 tony          1.8  
116                      CIMListenerIndicationDispatcher* _dispatcher;
117                    
118                      CIMExportResponseEncoder* _responseEncoder;
119                      CIMExportRequestDecoder*  _requestDecoder;
120                    
121                    };
122                    
123                    CIMListenerService::CIMListenerService(Uint32 portNumber, SSLContext* sslContext)
124                    :_portNumber(portNumber)
125                    ,_sslContext(sslContext)
126                    ,_monitor(NULL)
127                    ,_acceptor(NULL)
128                    ,_dieNow(false)
129                    ,_dispatcher(NULL)
130                    ,_responseEncoder(NULL)
131                    ,_requestDecoder(NULL)
132                    {
133                    }
134                    
135                    CIMListenerService::CIMListenerService(CIMListenerService& svc)
136 tony          1.8  :_portNumber(svc._portNumber)
137                    ,_sslContext(svc._sslContext)
138                    ,_monitor(NULL)
139                    ,_acceptor(NULL)
140                    ,_dieNow(svc._dieNow)
141                    ,_dispatcher(NULL)
142                    ,_responseEncoder(NULL)
143                    ,_requestDecoder(NULL)
144                    {
145                    }
146                    CIMListenerService::~CIMListenerService()
147                    {
148 kumpf         1.36     // if port is alive, clean up the port
149                        //delete _sslContext;
150 tony          1.8  
151 kumpf         1.36     delete _responseEncoder;
152 tony          1.8  
153 kumpf         1.36     delete _requestDecoder;
154 kumpf         1.1  
155 kumpf         1.36     //delete _dispatcher;
156 kumpf         1.1  
157 kumpf         1.36     delete _acceptor;
158 kumpf         1.1  
159 kumpf         1.36     delete _monitor;
160 tony          1.8  }
161 kumpf         1.1  
162 tony          1.8  void CIMListenerService::init()
163 kumpf         1.1  {
164 tony          1.8  	PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::init");
165 kumpf         1.1  
166 vijay.eli     1.33   if(NULL == _monitor) _monitor = new Monitor();
167 david.dillard 1.31 
168 tony          1.8  	//_dispatcher = new CIMListenerIndicationDispatcher();
169 kumpf         1.1  
170 vijay.eli     1.33   if(NULL == _responseEncoder) _responseEncoder = new CIMExportResponseEncoder();
171                      if(NULL == _requestDecoder) _requestDecoder = new CIMExportRequestDecoder(
172                                                          _dispatcher,_responseEncoder->getQueueId());
173 tony          1.8  
174 vijay.eli     1.33   if(NULL == _acceptor) _acceptor = new HTTPAcceptor(
175 david.dillard 1.31 		 _monitor,
176                    		 _requestDecoder,
177                    		 false,
178                    		 _portNumber,
179 kumpf         1.19 		 _sslContext,
180                                     false);
181 kumpf         1.1  
182 chuck         1.20   bind();
183 kumpf         1.1  
184 chuck         1.20   PEG_METHOD_EXIT();
185 tony          1.8  }
186 david.dillard 1.34 
187 tony          1.8  void CIMListenerService::bind()
188                    {
189 chuck         1.20   if(_acceptor!=NULL)
190                        { // Bind to the port
191                          _acceptor->bind();
192 tony          1.8  
193 chuck         1.20       //listener.addAcceptor(false, portNumberHttp, false);
194                          Logger::put(Logger::STANDARD_LOG, System::CIMLISTENER, Logger::INFORMATION,
195 tony          1.8                          "Listening on HTTP port $0.", _portNumber);
196 kumpf         1.1  
197 chuck         1.20     }
198 tony          1.8  }
199 chuck         1.20 
200 tony          1.8  void CIMListenerService::runForever()
201                    {
202 kumpf         1.40.2.1     if (!_dieNow)
203 dj.gorey      1.14         {
204 kumpf         1.40.2.1         _monitor->run(500000);
205                                static struct timeval lastIdleCleanupTime = {0, 0};
206                                struct timeval now;
207                                gettimeofday(&now, 0);
208                                if (now.tv_sec - lastIdleCleanupTime.tv_sec > 300)
209                                {
210                                    lastIdleCleanupTime.tv_sec = now.tv_sec;
211                                    try
212                                    {
213                                        MessageQueueService::get_thread_pool()->cleanupIdleThreads();
214                                    }
215                                    catch(...)
216                                    {
217                                        // Ignore!
218                                    }
219                                }
220 chuck         1.20         }
221 tony          1.8      }
222 kumpf         1.1      
223 tony          1.8      void CIMListenerService::shutdown()
224                        {
225                            PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::shutdown()");
226 kumpf         1.1      
227 tony          1.8          _dieNow = true;
228 a.arora       1.21         _monitor->tickle();
229 kumpf         1.1      
230 kumpf         1.4          PEG_METHOD_EXIT();
231 kumpf         1.1      }
232                        
233 tony          1.8      void CIMListenerService::resume()
234 kumpf         1.1      {
235 tony          1.8          PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::resume()");
236 kumpf         1.1      
237 tony          1.8          if(_acceptor!=NULL)
238                                _acceptor->reopenConnectionSocket();
239 kumpf         1.1      
240 kumpf         1.4          PEG_METHOD_EXIT();
241 kumpf         1.1      }
242                        
243 tony          1.8      void CIMListenerService::stopClientConnection()
244 kumpf         1.1      {
245 tony          1.8          PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::stopClientConnection()");
246 kumpf         1.1      
247 kumpf         1.10         // tell Monitor to stop listening for client connections
248 chuck         1.22         _monitor->stopListeningForConnections(true);
249 kumpf         1.10     
250                            //
251                            // Wait 150 milliseconds to allow time for the Monitor to stop
252                            // listening for client connections.
253                            //
254                            // This wait time is the timeout value for the select() call
255                            // in the Monitor's run() method (currently set to 100
256                            // milliseconds) plus a delta of 50 milliseconds.  The reason
257                            // for the wait here is to make sure that the Monitor entries
258                            // are updated before closing the connection sockets.
259                            //
260 a.arora       1.21         // pegasus_sleep(150); Not needed now due to the semaphore in the Monitor
261 david.dillard 1.31     
262 tony          1.8          if(_acceptor!=NULL)
263                            _acceptor->closeConnectionSocket();
264 kumpf         1.1      
265 kumpf         1.4          PEG_METHOD_EXIT();
266 kumpf         1.1      }
267                        
268 chuck         1.23     Uint32 CIMListenerService::getOutstandingRequestCount()
269                        {
270                            return _acceptor->getOutstandingRequestCount();
271                        }
272 tony          1.8      
273                        CIMListenerIndicationDispatcher* CIMListenerService::getIndicationDispatcher() const
274 kumpf         1.1      {
275 david.dillard 1.32         return _dispatcher;
276 tony          1.8      }
277 david.dillard 1.34     
278 tony          1.8      void CIMListenerService::setIndicationDispatcher(CIMListenerIndicationDispatcher* dispatcher)
279                        {
280 david.dillard 1.32         _dispatcher = dispatcher;
281 kumpf         1.1      }
282                        
283 david.dillard 1.34     Uint32 CIMListenerService::getPortNumber() const
284                        {
285                        
286                            Uint32 portNumber = _portNumber;
287                        
288                            if (( portNumber == 0 ) && ( _acceptor != 0 ))
289                            {
290                                portNumber = _acceptor->getPortNumber();
291                            }
292                        
293                            return(portNumber);
294                        }
295                        
296 tony          1.8      PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL CIMListenerService::_listener_routine(void *param)
297 kumpf         1.1      {
298 konrad.r      1.37       try { 
299 david.dillard 1.32         AutoPtr<CIMListenerService> svc(reinterpret_cast<CIMListenerService *>(param));
300 kumpf         1.1      
301 david.dillard 1.32         //svc->init(); bug 1394
302                            while(!svc->terminated())
303                            {
304 chuck         1.20     #if defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU)
305 david.dillard 1.32             pthread_testcancel();
306 chuck         1.20     #endif
307 david.dillard 1.32             svc->runForever();
308                            }
309 konrad.r      1.37       } catch (...) 
310                          { 
311                                Tracer::trace(TRC_SERVER, Tracer::LEVEL2,
312                        			"Unknown exception thrown in _listener_routine.");
313                          }
314 david.dillard 1.32         return 0;
315 tony          1.8      }
316                        
317                        /////////////////////////////////////////////////////////////////////////////
318                        // CIMListenerRep
319                        /////////////////////////////////////////////////////////////////////////////
320                        class CIMListenerRep
321                        {
322                        public:
323                        	CIMListenerRep(Uint32 portNumber, SSLContext* sslContext=NULL);
324                          ~CIMListenerRep();
325                        
326                        	Uint32 getPortNumber() const;
327                        
328                        	SSLContext* getSSLContext() const;
329                        	void setSSLContext(SSLContext* sslContext);
330 david.dillard 1.31     
331 tony          1.8      	void start();
332                        	void stop();
333                        
334                        	Boolean isAlive();
335                        
336                        	Boolean addConsumer(CIMIndicationConsumer* consumer);
337                        	Boolean removeConsumer(CIMIndicationConsumer* consumer);
338                        
339                        private:
340 chuck         1.23       Boolean waitForPendingRequests(Uint32 shutdownTimeout);
341                        
342                          Uint32 _portNumber;
343                          SSLContext* _sslContext;
344 tony          1.8      
345                          CIMListenerIndicationDispatcher* _dispatcher;
346 chuck         1.23       ThreadPool* _thread_pool;
347 david.dillard 1.31       CIMListenerService* _svc;
348 chuck         1.20       Semaphore *_listener_sem;
349 tony          1.8      };
350                        
351                        CIMListenerRep::CIMListenerRep(Uint32 portNumber, SSLContext* sslContext)
352                        :_portNumber(portNumber)
353                        ,_sslContext(sslContext)
354                        ,_dispatcher(new CIMListenerIndicationDispatcher())
355                        ,_thread_pool(NULL)
356 chuck         1.20     ,_svc(NULL)
357                        ,_listener_sem(NULL)
358 tony          1.8      {
359                        }
360 david.dillard 1.31     
361 tony          1.8      CIMListenerRep::~CIMListenerRep()
362                        {
363 david.dillard 1.31         // if port is alive, clean up the port
364                            if (_thread_pool != 0)
365                            {
366                                // Block incoming export requests and unbind the port
367                                _svc->stopClientConnection();
368                        
369                                // Wait until pending export requests in the server are done.
370                                waitForPendingRequests(10);
371 chuck         1.23     
372 david.dillard 1.31             // Shutdown the CIMListenerService
373                                _svc->shutdown();
374                            }
375 chuck         1.20     
376                            delete _sslContext;
377                            delete _dispatcher;
378                            delete _thread_pool;
379                            delete _listener_sem;
380 tony          1.8      
381 chuck         1.20       // don't delete _svc, this is deleted by _listener_routine
382 tony          1.8      }
383                        
384                        Uint32 CIMListenerRep::getPortNumber() const
385                        {
386 david.dillard 1.34         Uint32 portNumber;
387                        
388                            if ( _svc == 0 )
389                            {
390                                portNumber = _portNumber;
391                            }
392                            else portNumber = _svc->getPortNumber();
393                        
394                            return portNumber;
395 tony          1.8      }
396 kumpf         1.1      
397 tony          1.8      SSLContext* CIMListenerRep::getSSLContext() const
398                        {
399 david.dillard 1.31         return _sslContext;
400 kumpf         1.1      }
401 david.dillard 1.31     
402 tony          1.8      void CIMListenerRep::setSSLContext(SSLContext* sslContext)
403                        {
404 david.dillard 1.31         delete _sslContext;
405                            _sslContext = sslContext;
406                        }
407 kumpf         1.1      
408 tony          1.8      void CIMListenerRep::start()
409 kumpf         1.1      {
410 david.dillard 1.31         // spawn a thread to do this
411                            if(_thread_pool==0)
412 chuck         1.20         {
413 david.dillard 1.31             AutoPtr<CIMListenerService> svc(new CIMListenerService(_portNumber,_sslContext));
414 chuck         1.20     
415 david.dillard 1.31             svc->setIndicationDispatcher(_dispatcher);
416                                svc->init();
417 chuck         1.20     
418 david.dillard 1.31             struct timeval deallocateWait = {15, 0};
419                                AutoPtr<ThreadPool> threadPool(new ThreadPool(0, "Listener", 0, 1, deallocateWait));
420                                AutoPtr<Semaphore> sem(new Semaphore(0));
421 konrad.r      1.38             if (threadPool->allocate_and_awaken(svc.get(), CIMListenerService::_listener_routine, sem.get()) != PEGASUS_THREAD_OK)
422                            	{
423                        	    Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
424                        			"Not enough threads to start CIMListernerService.");
425                         
426                        	    Tracer::trace(TRC_SERVER, Tracer::LEVEL2,
427                        			"Could not allocate thread for CIMListenerService::_listener_routine."); 
428                        	    throw Exception(MessageLoaderParms("Listener.CIMListener.CANNOT_ALLOCATE_THREAD",
429                        				"Could not allocate thread."));
430                                }
431 david.dillard 1.31             Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER, Logger::INFORMATION,
432                                                "CIMListener started");
433                        
434                                _svc = svc.release();
435                                _thread_pool = threadPool.release();
436                                _listener_sem = sem.release();
437                            }
438 tony          1.8      }
439 kumpf         1.1      
440 tony          1.8      void CIMListenerRep::stop()
441                        {
442 chuck         1.20       if(_thread_pool!=NULL)
443 david.dillard 1.31       {
444 chuck         1.20         //
445                            // Graceful shutdown of the listener service
446                            //
447                        
448                            // Block incoming export requests and unbind the port
449                            _svc->stopClientConnection();
450 chuck         1.23     
451                            // Wait until pending export requests in the server are done.
452 chuck         1.24         waitForPendingRequests(10);
453 david.dillard 1.31     
454 chuck         1.20         // Shutdown the CIMListenerService
455                            _svc->shutdown();
456                        
457                            // Wait for the _listener_routine thread to exit.
458                            // The thread could be delivering an export, so give it 3sec.
459                            // Note that _listener_routine deletes the CIMListenerService,
460                            // so no need to delete _svc.
461                            try
462                            {
463 david.dillard 1.31           _listener_sem->time_wait(3000);
464 chuck         1.20         }
465 david.dillard 1.34         catch (const TimeOut &)
466 chuck         1.20         {
467                              // No need to do anything, the thread pool will be deleted below
468                              // to cancel the _listener_routine thread if it is still running.
469                            }
470                        
471                            delete _listener_sem;
472                            _listener_sem = NULL;
473 david.dillard 1.31     
474 chuck         1.20         // Delete the thread pool.  This cancels the listener thread if it is still
475                            // running.
476                            delete _thread_pool;
477                            _thread_pool = NULL;
478                        
479                            Logger::put(Logger::STANDARD_LOG,System::CIMLISTENER,
480                        		Logger::INFORMATION,
481                        		"CIMListener stopped");
482                          }
483 kumpf         1.1      }
484                        
485 tony          1.8      Boolean CIMListenerRep::isAlive()
486 kumpf         1.1      {
487 tony          1.8      	return (_thread_pool!=NULL)?true:false;
488                        }
489 kumpf         1.1      
490 tony          1.8      Boolean CIMListenerRep::addConsumer(CIMIndicationConsumer* consumer)
491                        {
492                        	return _dispatcher->addConsumer(consumer);
493                        }
494                        Boolean CIMListenerRep::removeConsumer(CIMIndicationConsumer* consumer)
495                        {
496                        	return _dispatcher->removeConsumer(consumer);
497                        }
498 kumpf         1.1      
499 chuck         1.23     Boolean CIMListenerRep::waitForPendingRequests(Uint32 shutdownTimeout)
500                        {
501                          // Wait for 10 sec max
502                          Uint32 reqCount;
503                          Uint32 countDown = shutdownTimeout * 10;
504                          for (; countDown > 0; countDown--)
505                          {
506                            reqCount = _svc->getOutstandingRequestCount();
507                            if (reqCount > 0)
508                              pegasus_sleep(100);
509                            else
510                              return true;
511                          }
512 david.dillard 1.31     
513 chuck         1.23       return false;
514 david.dillard 1.31     }
515 chuck         1.23     
516 tony          1.8      /////////////////////////////////////////////////////////////////////////////
517                        // CIMListener
518                        /////////////////////////////////////////////////////////////////////////////
519                        CIMListener::CIMListener(Uint32 portNumber, SSLContext* sslContext)
520                        :_rep(new CIMListenerRep(portNumber,sslContext))
521                        {
522                        }
523                        CIMListener::~CIMListener()
524                        {
525                        	if(_rep!=NULL)
526 tony          1.9      		delete static_cast<CIMListenerRep*>(_rep);
527 tony          1.8      	_rep=NULL;
528                        }
529 david.dillard 1.31     
530 tony          1.8      Uint32 CIMListener::getPortNumber() const
531                        {
532                        	return static_cast<CIMListenerRep*>(_rep)->getPortNumber();
533 kumpf         1.1      }
534                        
535 tony          1.8      SSLContext* CIMListener::getSSLContext() const
536                        {
537                        	return static_cast<CIMListenerRep*>(_rep)->getSSLContext();
538                        }
539                        void CIMListener::setSSLContext(SSLContext* sslContext)
540                        {
541                        	static_cast<CIMListenerRep*>(_rep)->setSSLContext(sslContext);
542                        }
543                        void CIMListener::start()
544 kumpf         1.1      {
545 tony          1.8      	static_cast<CIMListenerRep*>(_rep)->start();
546                        }
547                        void CIMListener::stop()
548                        {
549                        	static_cast<CIMListenerRep*>(_rep)->stop();
550                        }
551 kumpf         1.1      
552 aruran.ms     1.35     Boolean CIMListener::isAlive() const
553 tony          1.8      {
554                        	return static_cast<CIMListenerRep*>(_rep)->isAlive();
555                        }
556 kumpf         1.1      
557 tony          1.8      Boolean CIMListener::addConsumer(CIMIndicationConsumer* consumer)
558                        {
559                        	return static_cast<CIMListenerRep*>(_rep)->addConsumer(consumer);
560                        }
561                        Boolean CIMListener::removeConsumer(CIMIndicationConsumer* consumer)
562                        {
563                        	return static_cast<CIMListenerRep*>(_rep)->removeConsumer(consumer);
564 kumpf         1.1      }
565                        
566                        PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2