version 1.18, 2007/06/26 20:26:16
|
version 1.19, 2007/08/13 11:23:19
|
|
|
_dieNow(0), | _dieNow(0), |
_shutdownSem(0), | _shutdownSem(0), |
_monitor(0), | _monitor(0), |
#ifdef PEGASUS_ENABLE_IPV6 |
|
_ip6Acceptor(NULL), | _ip6Acceptor(NULL), |
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
_ip4Acceptor(NULL), | _ip4Acceptor(NULL), |
#endif |
|
_responseEncoder(0), | _responseEncoder(0), |
_requestDecoder(0), | _requestDecoder(0), |
_listening_thread(0), | _listening_thread(0), |
|
|
{ | { |
} | } |
| |
Boolean ListenerService::initializeListener(Uint32 portNumber, Boolean useSSL, SSLContext* sslContext) |
Boolean ListenerService::initializeListener(Uint32 portNumber, |
|
Boolean useSSL, SSLContext* sslContext) |
{ | { |
PEG_METHOD_ENTER(TRC_LISTENER, "ListenerService::initializeListener"); | PEG_METHOD_ENTER(TRC_LISTENER, "ListenerService::initializeListener"); |
| |
if (_initialized) | if (_initialized) |
{ | { |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, "Warning: The listener is already initialized."); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, |
|
"Warning: The listener is already initialized."); |
return true; | return true; |
} | } |
| |
|
|
| |
if (_useSSL && (_sslContext == NULL)) | if (_useSSL && (_sslContext == NULL)) |
{ | { |
throw Exception(MessageLoaderParms("DynListener.ListenerService.INVALID_SSL_CONFIGURATION", |
throw Exception(MessageLoaderParms( |
|
"DynListener.ListenerService.INVALID_SSL_CONFIGURATION", |
"Invalid SSL configuration: No SSLContext was specified.")); | "Invalid SSL configuration: No SSLContext was specified.")); |
} | } |
| |
if (!_useSSL && _sslContext) | if (!_useSSL && _sslContext) |
{ | { |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, "Warning: An SSLContext was specified for a non-SSL configuration."); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, |
|
"Warning: An SSLContext was specified for a non-SSL configuration."); |
} | } |
| |
_dispatcher = new DynamicListenerIndicationDispatcher(_consumerManager); | _dispatcher = new DynamicListenerIndicationDispatcher(_consumerManager); |
|
|
| |
if (!_initialized) | if (!_initialized) |
{ | { |
throw Exception(MessageLoaderParms("DynListener.ListenerService.NOT_INITIALIZED", |
throw Exception(MessageLoaderParms( |
|
"DynListener.ListenerService.NOT_INITIALIZED", |
"Error: You must initialize the listener prior to running it.")); | "Error: You must initialize the listener prior to running it.")); |
} | } |
| |
if (_running) | if (_running) |
{ | { |
throw Exception(MessageLoaderParms("DynListener.ListenerService.ALREADY_RUNNING", |
throw Exception(MessageLoaderParms( |
|
"DynListener.ListenerService.ALREADY_RUNNING", |
"Error: The listener is already running.")); | "Error: The listener is already running.")); |
} | } |
| |
_monitor = new Monitor(); | _monitor = new Monitor(); |
| |
#ifdef PEGASUS_ENABLE_IPV6 | #ifdef PEGASUS_ENABLE_IPV6 |
|
if (System::isIPv6StackActive()) |
|
{ |
_ip6Acceptor = new HTTPAcceptor( | _ip6Acceptor = new HTTPAcceptor( |
_monitor, | _monitor, |
_requestDecoder, | _requestDecoder, |
|
|
_portNumber, | _portNumber, |
_sslContext, | _sslContext, |
false); | false); |
|
} |
|
#ifndef PEGASUS_OS_TYPE_WINDOWS |
|
else |
#endif | #endif |
|
#endif |
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
{ |
_ip4Acceptor = new HTTPAcceptor( | _ip4Acceptor = new HTTPAcceptor( |
_monitor, | _monitor, |
_requestDecoder, | _requestDecoder, |
|
|
_portNumber, | _portNumber, |
_sslContext, | _sslContext, |
false); | false); |
#endif |
} |
| |
//create listening thread | //create listening thread |
_listening_thread = new Thread(_listener_routine, this, 0); | _listening_thread = new Thread(_listener_routine, this, 0); |
| |
//bind listener socket | //bind listener socket |
#ifdef PEGASUS_ENABLE_IPV6 |
if (_ip6Acceptor) |
|
{ |
_ip6Acceptor->bind(); | _ip6Acceptor->bind(); |
#endif |
} |
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
if (_ip4Acceptor) |
|
{ |
_ip4Acceptor->bind(); | _ip4Acceptor->bind(); |
#endif |
} |
| |
//start listening thread | //start listening thread |
ThreadStatus rtn = PEGASUS_THREAD_OK; | ThreadStatus rtn = PEGASUS_THREAD_OK; |
|
|
delete _listening_thread; _listening_thread = 0; | delete _listening_thread; _listening_thread = 0; |
_running = true; | _running = true; |
shutdownListener(); | shutdownListener(); |
throw Exception(MessageLoaderParms("DynListener.ListenerService.CANNOT_ALLOCATE_THREAD", |
throw Exception(MessageLoaderParms( |
|
"DynListener.ListenerService.CANNOT_ALLOCATE_THREAD", |
"Error: Cannot allocate thread.")); | "Error: Cannot allocate thread.")); |
} | } |
| |
|
|
delete _polling_thread; _polling_thread = 0; | delete _polling_thread; _polling_thread = 0; |
_running = true; | _running = true; |
shutdownListener(); | shutdownListener(); |
throw Exception(MessageLoaderParms("DynListener.ListenerService.CANNOT_ALLOCATE_THREAD", |
throw Exception(MessageLoaderParms( |
|
"DynListener.ListenerService.CANNOT_ALLOCATE_THREAD", |
"Error: Cannot allocate thread.")); | "Error: Cannot allocate thread.")); |
} | } |
} | } |
|
|
return true; | return true; |
} | } |
| |
ThreadReturnType PEGASUS_THREAD_CDECL ListenerService::_listener_routine(void *param) |
ThreadReturnType PEGASUS_THREAD_CDECL |
|
ListenerService::_listener_routine(void *param) |
{ | { |
PEG_METHOD_ENTER(TRC_LISTENER, "ListenerService::_listener_routine"); | PEG_METHOD_ENTER(TRC_LISTENER, "ListenerService::_listener_routine"); |
| |
Thread *myself = reinterpret_cast<Thread *>(param); | Thread *myself = reinterpret_cast<Thread *>(param); |
ListenerService* listenerService = reinterpret_cast<ListenerService*>(myself->get_parm()); |
ListenerService* listenerService = |
|
reinterpret_cast<ListenerService*>(myself->get_parm()); |
| |
while (!(listenerService->_dieNow)) | while (!(listenerService->_dieNow)) |
{ | { |
|
|
} | } |
| |
| |
ThreadReturnType PEGASUS_THREAD_CDECL ListenerService::_polling_routine(void *param) |
ThreadReturnType PEGASUS_THREAD_CDECL |
|
ListenerService::_polling_routine(void *param) |
{ | { |
PEG_METHOD_ENTER(TRC_LISTENER, "ListenerService::_polling_routine"); | PEG_METHOD_ENTER(TRC_LISTENER, "ListenerService::_polling_routine"); |
| |
Thread *myself = reinterpret_cast<Thread *>(param); | Thread *myself = reinterpret_cast<Thread *>(param); |
ListenerService* listenerService = reinterpret_cast<ListenerService*>(myself->get_parm()); |
ListenerService* listenerService = |
|
reinterpret_cast<ListenerService*>(myself->get_parm()); |
| |
while (true) | while (true) |
{ | { |
try | try |
{ | { |
//do a timed wait so we do can process a shutdown signal immediately | //do a timed wait so we do can process a shutdown signal immediately |
listenerService->_shutdownSem->time_wait(listenerService->_consumerManager->getIdleTimeout()); |
listenerService->_shutdownSem->time_wait( |
|
listenerService->_consumerManager->getIdleTimeout()); |
| |
if (listenerService->_dieNow) | if (listenerService->_dieNow) |
{ | { |
|
|
break; | break; |
} | } |
| |
} catch (TimeOut&) |
} |
|
catch (TimeOut&) |
{ | { |
//time to check for idle consumers | //time to check for idle consumers |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL3, "Unloading idle consumers"); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL3, |
|
"Unloading idle consumers"); |
listenerService->_consumerManager->unloadIdleConsumers(); | listenerService->_consumerManager->unloadIdleConsumers(); |
} | } |
} | } |
|
|
| |
if (!_running) | if (!_running) |
{ | { |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL4, "Warning: The listener is not currently running."); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL4, |
|
"Warning: The listener is not currently running."); |
| |
return true; | return true; |
} | } |
|
|
//stop the monitor from accepting connections | //stop the monitor from accepting connections |
_monitor->stopListeningForConnections(true); | _monitor->stopListeningForConnections(true); |
| |
#ifdef PEGASUS_ENABLE_IPV6 |
if (_ip6Acceptor) |
|
{ |
_ip6Acceptor->closeConnectionSocket(); | _ip6Acceptor->closeConnectionSocket(); |
#endif |
} |
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
if (_ip4Acceptor) |
|
{ |
_ip4Acceptor->closeConnectionSocket(); | _ip4Acceptor->closeConnectionSocket(); |
#endif |
} |
| |
//allow client threads to complete, wait 10 sec max | //allow client threads to complete, wait 10 sec max |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL4, "ListenerService::Waiting for outstanding requests..."); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL4, |
|
"ListenerService::Waiting for outstanding requests..."); |
Uint32 reqCount; | Uint32 reqCount; |
Uint32 countDown = SHUTDOWN_TIMEOUT; | Uint32 countDown = SHUTDOWN_TIMEOUT; |
for (; countDown > 0; countDown--) | for (; countDown > 0; countDown--) |
{ | { |
reqCount = 0; | reqCount = 0; |
#ifdef PEGASUS_ENABLE_IPV6 |
if (_ip6Acceptor) |
|
{ |
reqCount = _ip6Acceptor->getOutstandingRequestCount(); | reqCount = _ip6Acceptor->getOutstandingRequestCount(); |
#endif |
} |
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
if (_ip4Acceptor) |
|
{ |
reqCount += _ip4Acceptor->getOutstandingRequestCount(); | reqCount += _ip4Acceptor->getOutstandingRequestCount(); |
#endif |
} |
if (reqCount > 0) | if (reqCount > 0) |
{ | { |
Threads::sleep(1000); | Threads::sleep(1000); |
|
|
} | } |
} | } |
| |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL4, "ListenerService::Finished waiting for outstanding requests."); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL4, |
|
"ListenerService::Finished waiting for outstanding requests."); |
| |
if (reqCount > 0) | if (reqCount > 0) |
{ | { |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, "ListenerService::Did not successfully process all incoming requests to the acceptor."); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, |
|
"ListenerService::Did not successfully process" |
|
" all incoming requests to the acceptor."); |
gracefulShutdown = false; | gracefulShutdown = false; |
} | } |
| |
|
|
delete _listening_thread; | delete _listening_thread; |
_listening_thread = 0; | _listening_thread = 0; |
| |
} catch (...) |
} |
|
catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, "Did not successfully stop monitor thread"); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, |
|
"Did not successfully stop monitor thread"); |
gracefulShutdown = false; | gracefulShutdown = false; |
} | } |
| |
|
|
delete _polling_thread; | delete _polling_thread; |
_polling_thread = 0; | _polling_thread = 0; |
| |
} catch (...) |
} |
|
catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, "Did not successfully stop polling thread"); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL2, |
|
"Did not successfully stop polling thread"); |
gracefulShutdown = false; | gracefulShutdown = false; |
} | } |
} | } |
//delete acceptor | //delete acceptor |
#ifdef PEGASUS_ENABLE_IPV6 |
|
delete _ip6Acceptor; | delete _ip6Acceptor; |
_ip6Acceptor = 0; | _ip6Acceptor = 0; |
#endif |
|
#if !defined (PEGASUS_ENABLE_IPV6) || defined (PEGASUS_OS_TYPE_WINDOWS) |
|
delete _ip4Acceptor; | delete _ip4Acceptor; |
_ip4Acceptor = 0; | _ip4Acceptor = 0; |
#endif |
|
| |
//delete monitor | //delete monitor |
delete _monitor; | delete _monitor; |
|
|
| |
if (gracefulShutdown) | if (gracefulShutdown) |
{ | { |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL4, "Listener shutdown gracefully"); |
PEG_TRACE_CSTRING(TRC_LISTENER, Tracer::LEVEL4, |
|
"Listener shutdown gracefully"); |
} | } |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |