Network: Fix TcpClient::PollConnection on Linux
This commit is contained in:
parent
602de2e772
commit
f52c43df49
|
|
@ -411,32 +411,40 @@ namespace Nz
|
|||
|
||||
SocketState SocketImpl::PollConnection(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error)
|
||||
{
|
||||
// http://developerweb.net/viewtopic.php?id=3196
|
||||
fd_set localSet;
|
||||
FD_ZERO(&localSet);
|
||||
FD_SET(handle, &localSet);
|
||||
// Wait until socket is available for writing or an error occurs (ie when connection succeeds or fails)
|
||||
pollfd descriptor;
|
||||
descriptor.events = POLLOUT;
|
||||
descriptor.fd = handle;
|
||||
descriptor.revents = 0;
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
|
||||
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
|
||||
|
||||
int ret = ::select(0, nullptr, &localSet, &localSet, (msTimeout != std::numeric_limits<UInt64>::max()) ? &tv : nullptr);
|
||||
if (ret > 0)
|
||||
int ret = ::poll(&descriptor, 1, (msTimeout != std::numeric_limits<UInt64>::max()) ? int(msTimeout) : -1);
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
int code = GetLastErrorCode(handle, error);
|
||||
if (code < 0) //< GetLastErrorCode() failed
|
||||
return SocketState_NotConnected;
|
||||
if (error)
|
||||
*error = TranslateErrnoToSocketError(GetLastErrorCode());
|
||||
|
||||
if (code)
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
else if (ret > 0)
|
||||
{
|
||||
if (descriptor.revents & (POLLERR | POLLHUP))
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToSocketError(code);
|
||||
*error = GetLastError(handle);
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
else if (descriptor.revents & POLLOUT)
|
||||
return SocketState_Connected;
|
||||
else
|
||||
{
|
||||
NazaraWarning("Socket " + String::Number(handle) + " was returned by poll without POLLOUT nor error events (events: 0x" + String::Number(descriptor.revents, 16) + ')');
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
}
|
||||
else if (ret == 0)
|
||||
else
|
||||
{
|
||||
// Still connecting
|
||||
if (error)
|
||||
{
|
||||
if (msTimeout > 0)
|
||||
|
|
@ -447,18 +455,6 @@ namespace Nz
|
|||
|
||||
return SocketState_Connecting;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToSocketError(GetLastErrorCode());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return SocketState_Connected;
|
||||
}
|
||||
|
||||
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2018 Jérôme Leclercq
|
||||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
|
|
@ -452,32 +452,40 @@ namespace Nz
|
|||
|
||||
SocketState SocketImpl::PollConnection(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error)
|
||||
{
|
||||
// http://developerweb.net/viewtopic.php?id=3196
|
||||
fd_set localSet;
|
||||
FD_ZERO(&localSet);
|
||||
FD_SET(handle, &localSet);
|
||||
// Wait until socket is available for writing or an error occurs (ie when connection succeeds or fails)
|
||||
WSAPOLLFD descriptor;
|
||||
descriptor.events = POLLWRNORM;
|
||||
descriptor.fd = handle;
|
||||
descriptor.revents = 0;
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
|
||||
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
|
||||
|
||||
int ret = ::select(0, nullptr, &localSet, &localSet, (msTimeout != std::numeric_limits<UInt64>::max()) ? &tv : nullptr);
|
||||
if (ret > 0)
|
||||
int ret = WSAPoll(&descriptor, 1, (msTimeout != std::numeric_limits<UInt64>::max()) ? INT(msTimeout) : INT(-1));
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
int code = GetLastErrorCode(handle, error);
|
||||
if (code < 0) //< GetLastErrorCode() failed
|
||||
return SocketState_NotConnected;
|
||||
if (error)
|
||||
*error = TranslateWSAErrorToSocketError(WSAGetLastError());
|
||||
|
||||
if (code)
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
else if (ret > 0)
|
||||
{
|
||||
if (descriptor.revents & (POLLERR | POLLHUP))
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateWSAErrorToSocketError(code);
|
||||
*error = GetLastError(handle);
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
else if (descriptor.revents & POLLWRNORM)
|
||||
return SocketState_Connected;
|
||||
else
|
||||
{
|
||||
NazaraWarning("Socket " + String::Number(handle) + " was returned by poll without POLLOUT nor error events (events: 0x" + String::Number(descriptor.revents, 16) + ')');
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
}
|
||||
else if (ret == 0)
|
||||
else
|
||||
{
|
||||
// Still connecting
|
||||
if (error)
|
||||
{
|
||||
if (msTimeout > 0)
|
||||
|
|
@ -488,18 +496,6 @@ namespace Nz
|
|||
|
||||
return SocketState_Connecting;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateWSAErrorToSocketError(WSAGetLastError());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return SocketState_Connected;
|
||||
}
|
||||
|
||||
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
|
||||
|
|
|
|||
Loading…
Reference in New Issue