Skip to content

Commit

Permalink
tfixes #45879 Refactor the socket code to resemble 2.8 code
Browse files Browse the repository at this point in the history
These changes seem to fix the problem with the socket hanging when we run under panda.
We are waiting to hear from panda on a hot-fix on their side, but in case that doesn't work then we may need to use our fix.

Change-Id: I3187fc900e344c249c760ca74d1e809c70b21f9c
Reviewed-on: https://gerrit.dechocorp.com/26627
Reviewed-by: Jeremy Stanley <jeremy@mozy.com>
Reviewed-by: Russ Simons <russs@mozy.com>
  • Loading branch information
pancho committed Dec 7, 2011
1 parent ec27d87 commit 5a76c9c
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 60 deletions.
113 changes: 53 additions & 60 deletions mordor/socket.cpp
Expand Up @@ -104,55 +104,6 @@ std::ostream &operator <<(std::ostream &os, Protocol protocol)
static LPFN_ACCEPTEX pAcceptEx = 0;
static LPFN_GETACCEPTEXSOCKADDRS pGetAcceptExSockaddrs = 0;
static LPFN_CONNECTEX ConnectEx = 0;
static boost::once_flag extendedFuncInitFlag = BOOST_ONCE_INIT;

void initExtendedFunctions()
{
if (g_useConnectEx->val() || g_useAcceptEx->val())
{
socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
DWORD bytes = 0;

if (g_useAcceptEx->val()) {
GUID acceptExGuid = WSAID_ACCEPTEX;
WSAIoctl(sock,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&acceptExGuid,
sizeof(GUID),
&pAcceptEx,
sizeof(LPFN_ACCEPTEX),
&bytes,
NULL,
NULL);

GUID getAcceptExSockaddrsGuid = WSAID_GETACCEPTEXSOCKADDRS;
WSAIoctl(sock,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&getAcceptExSockaddrsGuid,
sizeof(GUID),
&pGetAcceptExSockaddrs,
sizeof(LPFN_GETACCEPTEXSOCKADDRS),
&bytes,
NULL,
NULL);
}

if (g_useConnectEx->val()) {
GUID connectExGuid = WSAID_CONNECTEX;
WSAIoctl(sock,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&connectExGuid,
sizeof(GUID),
&ConnectEx,
sizeof(LPFN_CONNECTEX),
&bytes,
NULL,
NULL);
}

closesocket(sock);
}
}

namespace {

Expand All @@ -161,6 +112,43 @@ static struct Initializer {
{
WSADATA wd;
WSAStartup(MAKEWORD(2,2), &wd);
socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
DWORD bytes = 0;

GUID acceptExGuid = WSAID_ACCEPTEX;
WSAIoctl(sock,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&acceptExGuid,
sizeof(GUID),
&pAcceptEx,
sizeof(LPFN_ACCEPTEX),
&bytes,
NULL,
NULL);

GUID getAcceptExSockaddrsGuid = WSAID_GETACCEPTEXSOCKADDRS;
WSAIoctl(sock,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&getAcceptExSockaddrsGuid,
sizeof(GUID),
&pGetAcceptExSockaddrs,
sizeof(LPFN_GETACCEPTEXSOCKADDRS),
&bytes,
NULL,
NULL);

GUID connectExGuid = WSAID_CONNECTEX;
WSAIoctl(sock,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&connectExGuid,
sizeof(GUID),
&ConnectEx,
sizeof(LPFN_CONNECTEX),
&bytes,
NULL,
NULL);

closesocket(sock);
}
~Initializer()
{
Expand Down Expand Up @@ -203,9 +191,9 @@ Socket::Socket(IOManager *ioManager, int family, int type, int protocol, int ini
// lenient
MORDOR_ASSERT(type != 0);
#ifdef WINDOWS
boost::call_once(&initExtendedFunctions, extendedFuncInitFlag);

if (pAcceptEx && m_ioManager) {
m_useAcceptEx = g_useAcceptEx->val(); //remember the setting for the entire life of the socket
m_useConnectEx = g_useConnectEx->val(); //in case it is changed in the registry
if (m_useAcceptEx && pAcceptEx && m_ioManager) {
m_sock = socket(family, type, protocol);
MORDOR_LOG_LEVEL(g_log, m_sock == -1 ? Log::ERROR : Log::DEBUG) << this
<< " socket(" << (Family)family << ", " << (Type)type << ", "
Expand All @@ -226,7 +214,8 @@ Socket::Socket(int family, int type, int protocol)
m_isRegisteredForRemoteClose(false)
{
#ifdef WINDOWS
boost::call_once(&initExtendedFunctions, extendedFuncInitFlag);
m_useAcceptEx = g_useAcceptEx->val(); //remember the setting for the entire life of the socket
m_useConnectEx = g_useConnectEx->val(); //in case it is changed in the registry
#endif
// Windows accepts type == 0 as implying SOCK_STREAM; other OS's aren't so
// lenient
Expand Down Expand Up @@ -263,7 +252,8 @@ Socket::Socket(IOManager &ioManager, int family, int type, int protocol)
m_isRegisteredForRemoteClose(false)
{
#ifdef WINDOWS
boost::call_once(&initExtendedFunctions, extendedFuncInitFlag);
m_useAcceptEx = g_useAcceptEx->val(); //remember the setting for the entire life of the socket
m_useConnectEx = g_useConnectEx->val(); //in case it is changed in the registry
#endif
// Windows accepts type == 0 as implying SOCK_STREAM; other OS's aren't so
// lenient
Expand Down Expand Up @@ -348,6 +338,7 @@ Socket::bind(Address::ptr addr)
void
Socket::connect(const Address &to)
{

MORDOR_ASSERT(to.family() == m_family);
if (!m_ioManager) {
if (::connect(m_sock, to.name(), to.nameLen())) {
Expand All @@ -358,7 +349,7 @@ Socket::connect(const Address &to)
MORDOR_LOG_INFO(g_log) << this << " connect(" << m_sock << ", " << to << ")";
} else {
#ifdef WINDOWS
if (ConnectEx) {
if (m_useConnectEx && ConnectEx) {
if (!m_localAddress) {
// need to be bound, even to ADDR_ANY, before calling ConnectEx
switch (m_family) {
Expand Down Expand Up @@ -431,6 +422,7 @@ Socket::connect(const Address &to)
timeout = m_ioManager->registerTimer(m_sendTimeout, boost::bind(
&IOManager::cancelEvent, m_ioManager, (HANDLE)m_sock, &m_sendEvent));
Scheduler::yieldTo();

if (timeout)
timeout->cancel();
}
Expand Down Expand Up @@ -482,6 +474,7 @@ Socket::connect(const Address &to)
boost::bind(&Socket::cancelIo, this,
boost::ref(m_cancelledSend), WSAETIMEDOUT));
Scheduler::yieldTo();

m_fiber.reset();
m_scheduler = NULL;
if (timeout)
Expand Down Expand Up @@ -588,7 +581,7 @@ void
Socket::accept(Socket &target)
{
#ifdef WINDOWS
if (pAcceptEx && m_ioManager) {
if (m_useAcceptEx && pAcceptEx && m_ioManager) {
MORDOR_ASSERT(target.m_sock != -1);
} else {
MORDOR_ASSERT(target.m_sock == -1);
Expand All @@ -610,7 +603,7 @@ Socket::accept(Socket &target)
<< newsock << " (" << *target.remoteAddress() << ')';
} else {
#ifdef WINDOWS
if (pAcceptEx) {
if (m_useAcceptEx && pAcceptEx) {
m_ioManager->registerEvent(&m_receiveEvent);
unsigned char addrs[sizeof(SOCKADDR_STORAGE) * 2 + 16];
DWORD bytes;
Expand Down Expand Up @@ -657,7 +650,7 @@ Socket::accept(Socket &target)
}
sockaddr *localAddr = NULL, *remoteAddr = NULL;
INT localAddrLen, remoteAddrLen;
if (pGetAcceptExSockaddrs)
if (m_useAcceptEx && pGetAcceptExSockaddrs)
pGetAcceptExSockaddrs(addrs, 0, sizeof(SOCKADDR_STORAGE) + 16,
sizeof(SOCKADDR_STORAGE) + 16, &localAddr, &localAddrLen,
&remoteAddr, &remoteAddrLen);
Expand Down Expand Up @@ -1092,7 +1085,7 @@ Socket::cancelAccept()
if (m_cancelledReceive)
return;
m_cancelledReceive = ERROR_OPERATION_ABORTED;
if (pAcceptEx) {
if (m_useAcceptEx && pAcceptEx) {
m_ioManager->cancelEvent((HANDLE)m_sock, &m_receiveEvent);
}
if (m_hEvent && m_scheduler && m_fiber) {
Expand All @@ -1113,7 +1106,7 @@ Socket::cancelConnect()
if (m_cancelledSend)
return;
m_cancelledSend = ERROR_OPERATION_ABORTED;
if (ConnectEx) {
if (m_useConnectEx && ConnectEx) {
m_ioManager->cancelEvent((HANDLE)m_sock, &m_sendEvent);
}
if (m_hEvent && m_scheduler && m_fiber) {
Expand Down
3 changes: 3 additions & 0 deletions mordor/socket.h
Expand Up @@ -178,6 +178,9 @@ class Socket : public boost::enable_shared_from_this<Socket>, boost::noncopyable
Scheduler *m_scheduler;

AsyncEvent m_sendEvent, m_receiveEvent;
bool m_useAcceptEx; //Cache the values in case they are changed in the registry at
bool m_useConnectEx; //runtime

#endif
bool m_isConnected, m_isRegisteredForRemoteClose;
boost::signals2::signal<void ()> m_onRemoteClose;
Expand Down

0 comments on commit 5a76c9c

Please sign in to comment.