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)
|
SocketState SocketImpl::PollConnection(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error)
|
||||||
{
|
{
|
||||||
// http://developerweb.net/viewtopic.php?id=3196
|
// Wait until socket is available for writing or an error occurs (ie when connection succeeds or fails)
|
||||||
fd_set localSet;
|
pollfd descriptor;
|
||||||
FD_ZERO(&localSet);
|
descriptor.events = POLLOUT;
|
||||||
FD_SET(handle, &localSet);
|
descriptor.fd = handle;
|
||||||
|
descriptor.revents = 0;
|
||||||
|
|
||||||
timeval tv;
|
int ret = ::poll(&descriptor, 1, (msTimeout != std::numeric_limits<UInt64>::max()) ? int(msTimeout) : -1);
|
||||||
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
|
if (ret == SOCKET_ERROR)
|
||||||
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 code = GetLastErrorCode(handle, error);
|
if (error)
|
||||||
if (code < 0) //< GetLastErrorCode() failed
|
*error = TranslateErrnoToSocketError(GetLastErrorCode());
|
||||||
return SocketState_NotConnected;
|
|
||||||
|
|
||||||
if (code)
|
return SocketState_NotConnected;
|
||||||
|
}
|
||||||
|
else if (ret > 0)
|
||||||
|
{
|
||||||
|
if (descriptor.revents & (POLLERR | POLLHUP))
|
||||||
{
|
{
|
||||||
if (error)
|
if (error)
|
||||||
*error = TranslateErrnoToSocketError(code);
|
*error = GetLastError(handle);
|
||||||
|
|
||||||
return SocketState_NotConnected;
|
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 (error)
|
||||||
{
|
{
|
||||||
if (msTimeout > 0)
|
if (msTimeout > 0)
|
||||||
|
|
@ -447,18 +455,6 @@ namespace Nz
|
||||||
|
|
||||||
return SocketState_Connecting;
|
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)
|
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"
|
// This file is part of the "Nazara Engine - Network module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// 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)
|
SocketState SocketImpl::PollConnection(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error)
|
||||||
{
|
{
|
||||||
// http://developerweb.net/viewtopic.php?id=3196
|
// Wait until socket is available for writing or an error occurs (ie when connection succeeds or fails)
|
||||||
fd_set localSet;
|
WSAPOLLFD descriptor;
|
||||||
FD_ZERO(&localSet);
|
descriptor.events = POLLWRNORM;
|
||||||
FD_SET(handle, &localSet);
|
descriptor.fd = handle;
|
||||||
|
descriptor.revents = 0;
|
||||||
|
|
||||||
timeval tv;
|
int ret = WSAPoll(&descriptor, 1, (msTimeout != std::numeric_limits<UInt64>::max()) ? INT(msTimeout) : INT(-1));
|
||||||
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
|
if (ret == SOCKET_ERROR)
|
||||||
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 code = GetLastErrorCode(handle, error);
|
if (error)
|
||||||
if (code < 0) //< GetLastErrorCode() failed
|
*error = TranslateWSAErrorToSocketError(WSAGetLastError());
|
||||||
return SocketState_NotConnected;
|
|
||||||
|
|
||||||
if (code)
|
return SocketState_NotConnected;
|
||||||
|
}
|
||||||
|
else if (ret > 0)
|
||||||
|
{
|
||||||
|
if (descriptor.revents & (POLLERR | POLLHUP))
|
||||||
{
|
{
|
||||||
if (error)
|
if (error)
|
||||||
*error = TranslateWSAErrorToSocketError(code);
|
*error = GetLastError(handle);
|
||||||
|
|
||||||
return SocketState_NotConnected;
|
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 (error)
|
||||||
{
|
{
|
||||||
if (msTimeout > 0)
|
if (msTimeout > 0)
|
||||||
|
|
@ -488,18 +496,6 @@ namespace Nz
|
||||||
|
|
||||||
return SocketState_Connecting;
|
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)
|
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue