version 1.41, 2006/07/07 14:43:46
|
version 1.47.10.1, 2007/06/25 19:51:16
|
|
|
// | // |
//============================================================================== | //============================================================================== |
// | // |
// Author: Dong Xiang, EMC Corporation (xiang_dong@emc.com) |
|
// |
|
// Modified By: Dan Gorey (djgorey@us.ibm.com) |
|
// Amit K Arora, IBM (amita@in.ibm.com) for PEP#183 |
|
// Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) |
|
// David Dillard, VERITAS Software Corp. |
|
// (david.dillard@veritas.com) |
|
// Vijay Eli, IBM (vijay.eli@in.ibm.com) for bug#3425 |
|
// Aruran, IBM (ashanmug@in.ibm.com) for Bug# 3604 |
|
// |
|
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include "CIMListener.h" | #include "CIMListener.h" |
|
|
#include <Pegasus/Common/HTTPAcceptor.h> | #include <Pegasus/Common/HTTPAcceptor.h> |
#include <Pegasus/Common/PegasusVersion.h> | #include <Pegasus/Common/PegasusVersion.h> |
#include <Pegasus/Common/MessageLoader.h> | #include <Pegasus/Common/MessageLoader.h> |
|
#include <Pegasus/Common/Time.h> |
#include <Pegasus/ExportServer/CIMExportResponseEncoder.h> | #include <Pegasus/ExportServer/CIMExportResponseEncoder.h> |
#include <Pegasus/ExportServer/CIMExportRequestDecoder.h> | #include <Pegasus/ExportServer/CIMExportRequestDecoder.h> |
#include <Pegasus/Consumer/CIMIndicationConsumer.h> | #include <Pegasus/Consumer/CIMIndicationConsumer.h> |
|
|
*/ | */ |
Uint32 getPortNumber() const; | Uint32 getPortNumber() const; |
| |
static PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL |
static ThreadReturnType PEGASUS_THREAD_CDECL |
_listener_routine(void *param); | _listener_routine(void *param); |
| |
private: | private: |
|
|
SSLContext *_sslContext; | SSLContext *_sslContext; |
Monitor *_monitor; | Monitor *_monitor; |
Mutex _monitorMutex; | Mutex _monitorMutex; |
HTTPAcceptor *_acceptor; |
#ifdef PEGASUS_ENABLE_IPV6 |
|
HTTPAcceptor *_ip6Acceptor; |
|
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
HTTPAcceptor *_ip4Acceptor; |
|
#endif |
Boolean _dieNow; | Boolean _dieNow; |
CIMListenerIndicationDispatcher *_dispatcher; | CIMListenerIndicationDispatcher *_dispatcher; |
CIMExportResponseEncoder *_responseEncoder; | CIMExportResponseEncoder *_responseEncoder; |
|
|
_portNumber(portNumber), | _portNumber(portNumber), |
_sslContext(sslContext), | _sslContext(sslContext), |
_monitor(NULL), | _monitor(NULL), |
_acceptor(NULL), |
#ifdef PEGASUS_ENABLE_IPV6 |
|
_ip6Acceptor(NULL), |
|
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
_ip4Acceptor(NULL), |
|
#endif |
_dieNow(false), | _dieNow(false), |
_dispatcher(NULL), | _dispatcher(NULL), |
_responseEncoder(NULL), | _responseEncoder(NULL), |
|
|
_portNumber(svc._portNumber), | _portNumber(svc._portNumber), |
_sslContext(svc._sslContext), | _sslContext(svc._sslContext), |
_monitor(NULL), | _monitor(NULL), |
_acceptor(NULL), |
#ifdef PEGASUS_ENABLE_IPV6 |
|
_ip6Acceptor(NULL), |
|
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
_ip4Acceptor(NULL), |
|
#endif |
_dieNow(svc._dieNow), | _dieNow(svc._dieNow), |
_dispatcher(NULL), | _dispatcher(NULL), |
_responseEncoder(NULL), | _responseEncoder(NULL), |
|
|
{ | { |
delete _responseEncoder; | delete _responseEncoder; |
delete _requestDecoder; | delete _requestDecoder; |
delete _acceptor; |
#ifdef PEGASUS_ENABLE_IPV6 |
|
delete _ip6Acceptor; |
|
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
delete _ip4Acceptor; |
|
#endif |
delete _monitor; | delete _monitor; |
} | } |
| |
|
|
_requestDecoder = new CIMExportRequestDecoder( | _requestDecoder = new CIMExportRequestDecoder( |
_dispatcher, _responseEncoder->getQueueId()); | _dispatcher, _responseEncoder->getQueueId()); |
} | } |
|
#ifdef PEGASUS_ENABLE_IPV6 |
if (NULL == _acceptor) |
if (NULL == _ip6Acceptor) |
{ | { |
_acceptor = new HTTPAcceptor( |
_ip6Acceptor = new HTTPAcceptor( |
_monitor, _requestDecoder, false, _portNumber, _sslContext, false); |
_monitor, _requestDecoder, HTTPAcceptor::IPV6_CONNECTION, |
|
_portNumber, _sslContext, false); |
} | } |
|
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
if (NULL == _ip4Acceptor) |
|
{ |
|
_ip4Acceptor = new HTTPAcceptor( |
|
_monitor, _requestDecoder, HTTPAcceptor::IPV4_CONNECTION, |
|
_portNumber, _sslContext, false); |
|
} |
|
#endif |
bind(); | bind(); |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
|
|
| |
void CIMListenerService::bind() | void CIMListenerService::bind() |
{ | { |
if (_acceptor != NULL) |
#ifdef PEGASUS_ENABLE_IPV6 |
|
if (_ip6Acceptor != NULL) |
{ | { |
_acceptor->bind(); |
_ip6Acceptor->bind(); |
| |
Logger::put( | Logger::put( |
Logger::STANDARD_LOG, | Logger::STANDARD_LOG, |
System::CIMLISTENER, | System::CIMLISTENER, |
Logger::INFORMATION, | Logger::INFORMATION, |
"Listening on HTTP port $0.", |
"IPV6, Listening on HTTP port $0.", |
_portNumber); | _portNumber); |
} | } |
|
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
if (_ip4Acceptor != NULL) |
|
{ |
|
_ip4Acceptor->bind(); |
|
|
|
Logger::put( |
|
Logger::STANDARD_LOG, |
|
System::CIMLISTENER, |
|
Logger::INFORMATION, |
|
"IPV4, Listening on HTTP for port $0.", |
|
_portNumber); |
|
} |
|
#endif |
} | } |
| |
void CIMListenerService::runForever() | void CIMListenerService::runForever() |
{ | { |
static int modulator = 0; |
|
|
|
if (!_dieNow) | if (!_dieNow) |
{ | { |
if (false == _monitor->run(500000)) |
_monitor->run(500000); |
|
static struct timeval lastIdleCleanupTime = {0, 0}; |
|
struct timeval now; |
|
Time::gettimeofday(&now); |
|
if (now.tv_sec - lastIdleCleanupTime.tv_sec > 300) |
{ | { |
modulator++; |
lastIdleCleanupTime.tv_sec = now.tv_sec; |
try | try |
{ | { |
MessageQueueService::get_thread_pool()->cleanupIdleThreads(); | MessageQueueService::get_thread_pool()->cleanupIdleThreads(); |
|
|
void CIMListenerService::resume() | void CIMListenerService::resume() |
{ | { |
PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::resume()"); | PEG_METHOD_ENTER(TRC_LISTENER, "CIMListenerService::resume()"); |
|
#ifdef PEGASUS_ENABLE_IPV6 |
if (_acceptor != NULL) |
if (_ip6Acceptor != NULL) |
_acceptor->reopenConnectionSocket(); |
{ |
|
_ip6Acceptor->reopenConnectionSocket(); |
|
} |
|
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
if (_ip4Acceptor != NULL) |
|
{ |
|
_ip4Acceptor->reopenConnectionSocket(); |
|
} |
|
#endif |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
|
|
| |
// tell Monitor to stop listening for client connections | // tell Monitor to stop listening for client connections |
_monitor->stopListeningForConnections(true); | _monitor->stopListeningForConnections(true); |
|
#ifdef PEGASUS_ENABLE_IPV6 |
if (_acceptor != NULL) |
if (_ip6Acceptor != NULL) |
_acceptor->closeConnectionSocket(); |
{ |
|
_ip6Acceptor->closeConnectionSocket(); |
|
} |
|
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
if (_ip4Acceptor != NULL) |
|
{ |
|
_ip4Acceptor->closeConnectionSocket(); |
|
} |
|
#endif |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
Uint32 CIMListenerService::getOutstandingRequestCount() | Uint32 CIMListenerService::getOutstandingRequestCount() |
{ | { |
return _acceptor->getOutstandingRequestCount(); |
Uint32 cnt = 0; |
|
#ifdef PEGASUS_ENABLE_IPV6 |
|
cnt = _ip6Acceptor->getOutstandingRequestCount(); |
|
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
cnt += _ip4Acceptor->getOutstandingRequestCount(); |
|
#endif |
|
|
|
return cnt; |
} | } |
| |
CIMListenerIndicationDispatcher* | CIMListenerIndicationDispatcher* |
|
|
{ | { |
Uint32 portNumber = _portNumber; | Uint32 portNumber = _portNumber; |
| |
if ((portNumber == 0) && (_acceptor != 0)) |
#ifdef PEGASUS_ENABLE_IPV6 |
|
if ((portNumber == 0) && (_ip6Acceptor != 0)) |
{ | { |
portNumber = _acceptor->getPortNumber(); |
portNumber = _ip6Acceptor->getPortNumber(); |
} | } |
|
#endif |
|
|
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
if ((portNumber == 0) && (_ip4Acceptor != 0)) |
|
{ |
|
portNumber = _ip4Acceptor->getPortNumber(); |
|
} |
|
#endif |
| |
return (portNumber); | return (portNumber); |
} | } |
| |
PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL |
ThreadReturnType PEGASUS_THREAD_CDECL |
CIMListenerService::_listener_routine(void *param) | CIMListenerService::_listener_routine(void *param) |
{ | { |
CIMListenerService *svc = reinterpret_cast < CIMListenerService * >(param); | CIMListenerService *svc = reinterpret_cast < CIMListenerService * >(param); |
|
|
// svc->init(); bug 1394 | // svc->init(); bug 1394 |
while (!svc->terminated()) | while (!svc->terminated()) |
{ | { |
#if defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU) |
#if defined(PEGASUS_OS_DARWIN) |
pthread_testcancel(); | pthread_testcancel(); |
#endif | #endif |
svc->runForever(); | svc->runForever(); |
|
|
} | } |
catch(...) | catch(...) |
{ | { |
Tracer::trace(TRC_SERVER, Tracer::LEVEL2, |
PEG_TRACE_CSTRING(TRC_SERVER, Tracer::LEVEL2, |
"Unknown exception thrown in _listener_routine."); | "Unknown exception thrown in _listener_routine."); |
} | } |
| |
|
|
// _dieNow to true and called Monitor::tickle(). We must wait until we | // _dieNow to true and called Monitor::tickle(). We must wait until we |
// can obtain the _monitorMutex, indicating that we are no longer inside | // can obtain the _monitorMutex, indicating that we are no longer inside |
// Monitor::tickle(). | // Monitor::tickle(). |
svc->_monitorMutex.lock(pegasus_thread_self()); |
svc->_monitorMutex.lock(); |
svc->_monitorMutex.unlock(); | svc->_monitorMutex.unlock(); |
delete svc; | delete svc; |
| |
|
|
!= PEGASUS_THREAD_OK) | != PEGASUS_THREAD_OK) |
{ | { |
Logger::put( | Logger::put( |
Logger::STANDARD_LOG, System::CIMSERVER, |
Logger::STANDARD_LOG, System::CIMLISTENER, |
Logger::TRACE, | Logger::TRACE, |
"Not enough threads to start CIMListernerService."); | "Not enough threads to start CIMListernerService."); |
| |
Tracer::trace( |
PEG_TRACE_CSTRING( |
TRC_SERVER, | TRC_SERVER, |
Tracer::LEVEL2, | Tracer::LEVEL2, |
"Could not allocate thread for " | "Could not allocate thread for " |
|
|
{ | { |
reqCount = _svc->getOutstandingRequestCount(); | reqCount = _svc->getOutstandingRequestCount(); |
if (reqCount > 0) | if (reqCount > 0) |
pegasus_sleep(100); |
Threads::sleep(100); |
else | else |
return true; | return true; |
} | } |