version 1.26.4.1, 2008/01/02 21:05:03
|
version 1.27, 2007/07/27 18:37:17
|
|
|
#include <Pegasus/Common/Sharable.h> | #include <Pegasus/Common/Sharable.h> |
#include <Pegasus/Common/Logger.h> | #include <Pegasus/Common/Logger.h> |
#include <Pegasus/Common/System.h> | #include <Pegasus/Common/System.h> |
#include <Pegasus/Common/Tracer.h> |
|
| |
PEGASUS_NAMESPACE_BEGIN |
//------------------------------------------------------------------------------ |
|
// |
static Uint32 _socketInterfaceRefCount = 0; |
// PEGASUS_RETRY_SYSTEM_CALL() |
|
// |
Boolean Socket::timedConnect( |
// This macro repeats the given system call until it returns something |
SocketHandle socket, |
// other than EINTR. |
sockaddr* address, |
// |
int addressLength, |
//------------------------------------------------------------------------------ |
Uint32 timeoutMilliseconds) |
|
{ |
|
int connectResult; |
|
PEGASUS_RETRY_SYSTEM_CALL( |
|
::connect(socket, address, addressLength), connectResult); |
|
|
|
if (connectResult == 0) |
|
{ |
|
return true; |
|
} |
|
|
|
if (getSocketError() == PEGASUS_NETWORK_EINPROGRESS) |
|
{ |
|
PEG_TRACE((TRC_HTTP, Tracer::LEVEL4, |
|
"Connection to server in progress. Waiting up to %u milliseconds " |
|
"for the socket to become connected.", |
|
timeoutMilliseconds)); |
|
| |
fd_set fdwrite; |
#ifdef PEGASUS_OS_TYPE_WINDOWS |
FD_ZERO(&fdwrite); |
# define PEGASUS_RETRY_SYSTEM_CALL(EXPR, RESULT) RESULT = EXPR |
FD_SET(socket, &fdwrite); |
#else |
struct timeval timeoutValue = |
# define PEGASUS_RETRY_SYSTEM_CALL(EXPR, RESULT) \ |
{ timeoutMilliseconds/1000, timeoutMilliseconds%1000*1000 }; |
while (((RESULT = (EXPR)) == -1) && (errno == EINTR)) |
int selectResult = -1; |
#endif |
| |
PEGASUS_RETRY_SYSTEM_CALL( |
PEGASUS_NAMESPACE_BEGIN |
select(FD_SETSIZE, NULL, &fdwrite, NULL, &timeoutValue), |
|
selectResult); |
|
if (selectResult == 0) |
|
{ |
|
PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, |
|
"select() timed out waiting for the socket connection to be " |
|
"established."); |
|
return false; |
|
} |
|
else if (selectResult > 0) |
|
{ |
|
int optval; |
|
SocketLength optlen = sizeof(int); |
|
getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&optval, &optlen); |
|
if (optval == 0) |
|
{ |
|
PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4, |
|
"Connection with server established."); |
|
return true; |
|
} |
|
else |
|
{ |
|
PEG_TRACE((TRC_HTTP, Tracer::LEVEL2, |
|
"Did not connect, getsockopt() returned optval = %d", |
|
optval)); |
|
return false; |
|
} |
|
} |
|
else |
|
{ |
|
PEG_TRACE((TRC_HTTP, Tracer::LEVEL2, |
|
"select() returned error code %d", |
|
getSocketError())); |
|
return false; |
|
} |
|
} |
|
| |
PEG_TRACE((TRC_HTTP, Tracer::LEVEL2, |
static Uint32 _socketInterfaceRefCount = 0; |
"connect() returned error code %d", |
|
getSocketError())); |
|
return false; |
|
} |
|
| |
Sint32 Socket::read(SocketHandle socket, void* ptr, Uint32 size) | Sint32 Socket::read(SocketHandle socket, void* ptr, Uint32 size) |
{ | { |
|
|
} | } |
} | } |
| |
|
void Socket::enableBlocking(SocketHandle socket) |
|
{ |
|
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
unsigned long flag = 0; |
|
ioctlsocket(socket, FIONBIO, &flag); |
|
#else |
|
int flags = fcntl(socket, F_GETFL, 0); |
|
flags &= ~O_NONBLOCK; |
|
fcntl(socket, F_SETFL, flags); |
|
#endif |
|
} |
|
|
void Socket::disableBlocking(SocketHandle socket) | void Socket::disableBlocking(SocketHandle socket) |
{ | { |
#ifdef PEGASUS_OS_TYPE_WINDOWS | #ifdef PEGASUS_OS_TYPE_WINDOWS |
unsigned long flag = 1; // Use "flag = 0" to enable blocking |
unsigned long flag = 1; |
ioctlsocket(socket, FIONBIO, &flag); | ioctlsocket(socket, FIONBIO, &flag); |
#else | #else |
int flags = fcntl(socket, F_GETFL, 0); | int flags = fcntl(socket, F_GETFL, 0); |
flags |= O_NONBLOCK; // Use "flags &= ~O_NONBLOCK" to enable blocking |
flags |= O_NONBLOCK; |
fcntl(socket, F_SETFL, flags); | fcntl(socket, F_SETFL, flags); |
#endif | #endif |
} | } |
|
|
{ | { |
newSocket = socket(domain,type,protocol); | newSocket = socket(domain,type,protocol); |
| |
|
if ((newSocket != PEGASUS_INVALID_SOCKET) || |
|
(getSocketError() != PEGASUS_NETWORK_TRYAGAIN)) |
|
{ |
|
break; |
|
} |
|
|
|
#ifdef PEGASUS_OS_ZOS |
// The program should wait for transport layer to become ready. | // The program should wait for transport layer to become ready. |
| |
if (newSocket == PEGASUS_INVALID_SOCKET && |
|
getSocketError() == PEGASUS_NETWORK_TCPIP_TRYAGAIN ) |
|
{ |
|
if (sendTcpipMsg) | if (sendTcpipMsg) |
{ | { |
Logger::put_l( | Logger::put_l( |
|
|
} | } |
| |
System::sleep(30); | System::sleep(30); |
continue; |
#endif |
} |
|
else |
|
{ |
|
break; |
|
} |
|
} // wait for the transport layer become ready. | } // wait for the transport layer become ready. |
| |
// Is the socket in an unrecoverable error ? | // Is the socket in an unrecoverable error ? |