version 1.47, 2004/01/16 19:21:56
|
version 1.52, 2004/10/17 20:39:17
|
|
|
//%2003//////////////////////////////////////////////////////////////////////// |
//%2004//////////////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Development |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// Company, L. P., IBM Corp., The Open Group, Tivoli Systems. |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.; | // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.; |
// IBM Corp.; EMC Corporation, The Open Group. | // IBM Corp.; EMC Corporation, The Open Group. |
|
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; |
|
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
// | // |
// Permission is hereby granted, free of charge, to any person obtaining a copy | // Permission is hereby granted, free of charge, to any person obtaining a copy |
// of this software and associated documentation files (the "Software"), to | // of this software and associated documentation files (the "Software"), to |
|
|
// Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com) | // Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com) |
// Dave Rosckes (rosckes@us.ibm.com) | // Dave Rosckes (rosckes@us.ibm.com) |
// Denise Eckstein (denise.eckstein@hp.com) | // Denise Eckstein (denise.eckstein@hp.com) |
|
// Alagaraja Ramasubramanian (alags_raj@in.ibm.com) for Bug#1090 |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
|
|
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
|
static int MAX_CONNECTION_QUEUE_LENGTH = -1; |
|
|
|
|
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
// | // |
// HTTPAcceptorRep | // HTTPAcceptorRep |
|
|
MessageQueue* outputMessageQueue, | MessageQueue* outputMessageQueue, |
Boolean localConnection, | Boolean localConnection, |
Uint32 portNumber, | Uint32 portNumber, |
SSLContext * sslcontext) |
SSLContext * sslcontext, |
|
Boolean exportConnection) |
: Base(PEGASUS_QUEUENAME_HTTPACCEPTOR), // ATTN: Need unique names? | : Base(PEGASUS_QUEUENAME_HTTPACCEPTOR), // ATTN: Need unique names? |
_monitor(monitor), | _monitor(monitor), |
_outputMessageQueue(outputMessageQueue), | _outputMessageQueue(outputMessageQueue), |
|
|
_entry_index(-1), | _entry_index(-1), |
_localConnection(localConnection), | _localConnection(localConnection), |
_portNumber(portNumber), | _portNumber(portNumber), |
_sslcontext(sslcontext) |
_sslcontext(sslcontext), |
|
_exportConnection(exportConnection) |
{ | { |
Socket::initializeInterface(); | Socket::initializeInterface(); |
|
|
|
/* |
|
Platforms interpret the value of MAX_CONNECTION_QUEUE_LENGTH differently. Some platforms interpret |
|
the value literally, while others multiply a fudge factor. When the server is under |
|
stress from multiple clients with multiple requests, toggling this number may prevent clients from |
|
being dropped. Instead of hard coding the value, we allow an environment variable to be set which |
|
specifies a number greater than the maximum concurrent client connections possible. If this environment |
|
var is not specified, then MAX_CONNECTION_QUEUE_LENGTH = 15. |
|
*/ |
|
|
|
//To engage runtime backlog queue length: uncomment the following block AND comment out the line MAX_CONNECTION_QUEUE_LENGTH = 15 |
|
|
|
/* |
|
if(MAX_CONNECTION_QUEUE_LENGTH == -1){ |
|
#ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM |
|
#pragma convert(37) |
|
const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE"); |
|
EtoA(env); |
|
#pragma convert(0) |
|
#else |
|
const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE"); |
|
#endif |
|
if(!env){ |
|
MAX_CONNECTION_QUEUE_LENGTH = 15; |
|
}else{ |
|
char *end = NULL; |
|
MAX_CONNECTION_QUEUE_LENGTH = strtol(env, &end, 10); |
|
if(*end) |
|
MAX_CONNECTION_QUEUE_LENGTH = 15; |
|
cout << " MAX_CONNECTION_QUEUE_LENGTH = " << MAX_CONNECTION_QUEUE_LENGTH << endl; |
|
} |
|
} |
|
*/ |
|
MAX_CONNECTION_QUEUE_LENGTH = 15; |
|
|
} | } |
| |
HTTPAcceptor::~HTTPAcceptor() | HTTPAcceptor::~HTTPAcceptor() |
|
|
CloseConnectionMessage* closeConnectionMessage | CloseConnectionMessage* closeConnectionMessage |
= (CloseConnectionMessage*)message; | = (CloseConnectionMessage*)message; |
| |
_rep->_connection_mut.lock(pegasus_thread_self()); |
AutoMutex autoMut(_rep->_connection_mut); |
| |
for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++) | for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++) |
{ | { |
|
|
break; | break; |
} | } |
} | } |
_rep->_connection_mut.unlock(); |
|
break; | break; |
} | } |
| |
|
|
| |
// Set up listening on the given socket: | // Set up listening on the given socket: |
| |
int const MAX_CONNECTION_QUEUE_LENGTH = 15; |
//int const MAX_CONNECTION_QUEUE_LENGTH = 15; |
| |
if (listen(_rep->socket, MAX_CONNECTION_QUEUE_LENGTH) < 0) | if (listen(_rep->socket, MAX_CONNECTION_QUEUE_LENGTH) < 0) |
{ | { |
|
|
{ | { |
Uint32 count = 0; | Uint32 count = 0; |
| |
_rep->_connection_mut.lock(pegasus_thread_self()); |
AutoMutex autoMut(_rep->_connection_mut); |
if (_rep->connections.size() > 0) | if (_rep->connections.size() > 0) |
{ | { |
HTTPConnection* connection = _rep->connections[0]; | HTTPConnection* connection = _rep->connections[0]; |
count = connection->getRequestCount(); | count = connection->getRequestCount(); |
} | } |
_rep->_connection_mut.unlock(); |
|
return count; | return count; |
} | } |
| |
|
|
| |
// For each connection created by this object: | // For each connection created by this object: |
| |
_rep->_connection_mut.lock(pegasus_thread_self()); |
AutoMutex autoMut(_rep->_connection_mut); |
for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++) | for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++) |
{ | { |
HTTPConnection* connection = _rep->connections[i]; | HTTPConnection* connection = _rep->connections[i]; |
|
|
} | } |
| |
_rep->connections.clear(); | _rep->connections.clear(); |
_rep->_connection_mut.unlock(); |
|
} | } |
| |
void HTTPAcceptor::_acceptConnection() | void HTTPAcceptor::_acceptConnection() |
|
|
| |
// Create a new conection and add it to the connection list: | // Create a new conection and add it to the connection list: |
| |
MP_Socket * mp_socket = new MP_Socket(socket, _sslcontext); |
AutoPtr<MP_Socket> mp_socket(new MP_Socket(socket, _sslcontext, _exportConnection)); |
if (mp_socket->accept() < 0) | if (mp_socket->accept() < 0) |
{ | { |
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, | PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
|
return; | return; |
} | } |
| |
HTTPConnection* connection = new HTTPConnection( |
HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket, |
_monitor, mp_socket, this, static_cast<MessageQueue *>(_outputMessageQueue)); |
this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection); |
| |
// Solicit events on this new connection's socket: | // Solicit events on this new connection's socket: |
int index; | int index; |
|
|
return; | return; |
} | } |
| |
|
mp_socket.release(); |
|
|
// Save the socket for cleanup later: | // Save the socket for cleanup later: |
connection->_entry_index = index; | connection->_entry_index = index; |
_rep->_connection_mut.lock(pegasus_thread_self()); |
AutoMutex autoMut(_rep->_connection_mut); |
_rep->connections.append(connection); | _rep->connections.append(connection); |
_rep->_connection_mut.unlock(); |
|
} | } |
| |
AsyncDQueue<pegasus_acceptor> pegasus_acceptor::acceptors(true, 0); | AsyncDQueue<pegasus_acceptor> pegasus_acceptor::acceptors(true, 0); |