Fixes and tweaks to the networking impl
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "NetworkBase.h"
|
||||
|
||||
@@ -101,4 +101,3 @@ NetworkEndPoint NetworkBase::RemapEndPointToIPv6(NetworkEndPoint& endPoint)
|
||||
{
|
||||
return NetworkEndPoint();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,20 +5,27 @@
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
API_INJECT_CPP_CODE("#include \"Engine/Platform/Network.h\"");
|
||||
|
||||
#define SOCKGROUP_MAXCOUNT 64
|
||||
#define SOCKGROUP_ITEMSIZE 16
|
||||
|
||||
enum class FLAXENGINE_API NetworkProtocolType
|
||||
{
|
||||
/// <summary>Not specified.</summary>
|
||||
Undefined,
|
||||
/// <summary>User Datagram Protocol.</summary>
|
||||
Udp,
|
||||
/// <summary>Transmission Control Protocol.</summary>
|
||||
Tcp
|
||||
};
|
||||
|
||||
enum class FLAXENGINE_API NetworkIPVersion
|
||||
{
|
||||
/// <summary>Not specified.</summary>
|
||||
Undefined,
|
||||
/// <summary>Internet Protocol version 4.</summary>
|
||||
IPv4,
|
||||
/// <summary>Internet Protocol version 6.</summary>
|
||||
IPv6
|
||||
};
|
||||
|
||||
@@ -26,7 +33,7 @@ struct FLAXENGINE_API NetworkSocket
|
||||
{
|
||||
NetworkProtocolType Protocol = NetworkProtocolType::Undefined;
|
||||
NetworkIPVersion IPVersion = NetworkIPVersion::Undefined;
|
||||
byte Data[8] = {}; // sizeof SOCKET = unsigned __int64
|
||||
byte Data[8] = {};
|
||||
};
|
||||
|
||||
struct FLAXENGINE_API NetworkEndPoint
|
||||
@@ -34,26 +41,41 @@ struct FLAXENGINE_API NetworkEndPoint
|
||||
NetworkIPVersion IPVersion = NetworkIPVersion::Undefined;
|
||||
String Address;
|
||||
String Port;
|
||||
byte Data[28] = {}; // sizeof sockaddr_in6 , biggest sockaddr that we will use
|
||||
byte Data[28] = {};
|
||||
};
|
||||
|
||||
enum FLAXENGINE_API NetworkSocketOption
|
||||
enum class FLAXENGINE_API NetworkSocketOption
|
||||
{
|
||||
/// <summary>Enables debugging info recording.</summary>
|
||||
Debug,
|
||||
/// <summary>Allows local address reusing.</summary>
|
||||
ReuseAddr,
|
||||
/// <summary>Keeps connections alive.</summary>
|
||||
KeepAlive,
|
||||
/// <summary>Indicates that outgoing data should be sent on whatever interface the socket is bound to and not a routed on some other interface.</summary>
|
||||
DontRoute,
|
||||
/// <summary>Allows for sending broadcast data.</summary>
|
||||
Broadcast,
|
||||
/// <summary>Uses the local loopback address when sending data from this socket.</summary>
|
||||
UseLoopback,
|
||||
/// <summary>Lingers on close if data present.</summary>
|
||||
Linger,
|
||||
/// <summary>Allows out-of-bound data to be returned in-line with regular data.</summary>
|
||||
OOBInline,
|
||||
/// <summary>Socket send data buffer size.</summary>
|
||||
SendBuffer,
|
||||
/// <summary>Socket receive data buffer size.</summary>
|
||||
RecvBuffer,
|
||||
/// <summary>The timeout in milliseconds for blocking send calls.</summary>
|
||||
SendTimeout,
|
||||
/// <summary>The timeout in milliseconds for blocking receive calls.</summary>
|
||||
RecvTimeout,
|
||||
/// <summary>The last socket error code.</summary>
|
||||
Error,
|
||||
/// <summary>Enables the Nagle algorithm for TCP sockets.</summary>
|
||||
NoDelay,
|
||||
IPv6Only
|
||||
/// <summary>Enables IPv6 communication only for TCP socket.</summary>
|
||||
IPv6Only,
|
||||
};
|
||||
|
||||
struct FLAXENGINE_API NetworkSocketState
|
||||
@@ -68,12 +90,12 @@ struct FLAXENGINE_API NetworkSocketState
|
||||
struct FLAXENGINE_API NetworkSocketGroup
|
||||
{
|
||||
uint32 Count = 0;
|
||||
byte Data[SOCKGROUP_MAXCOUNT * 16] = {};
|
||||
byte Data[SOCKGROUP_MAXCOUNT * SOCKGROUP_ITEMSIZE] = {};
|
||||
};
|
||||
|
||||
class FLAXENGINE_API NetworkBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
/// <summary>
|
||||
/// Creates a new native socket.
|
||||
/// </summary>
|
||||
@@ -241,4 +263,3 @@ class FLAXENGINE_API NetworkBase
|
||||
/// <returns>The ipv6 end point.</returns>
|
||||
static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint& endPoint);
|
||||
};
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ void UWPPlatform::BeforeExit()
|
||||
|
||||
void UWPPlatform::Exit()
|
||||
{
|
||||
Win32Platform::Exit();
|
||||
}
|
||||
|
||||
int32 UWPPlatform::GetDpi()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Win32Network.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
@@ -12,8 +12,10 @@
|
||||
static_assert(sizeof NetworkSocket::Data >= sizeof SOCKET, "NetworkSocket::Data is not big enough to contains SOCKET !");
|
||||
static_assert(sizeof NetworkEndPoint::Data >= sizeof sockaddr_in6, "NetworkEndPoint::Data is not big enough to contains sockaddr_in6 !");
|
||||
|
||||
// @formatter:off
|
||||
static const IN6_ADDR v4MappedPrefix = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } };
|
||||
// @formatter:on
|
||||
|
||||
/*
|
||||
* Known issues :
|
||||
@@ -24,9 +26,9 @@ static String GetErrorMessage(int error)
|
||||
{
|
||||
wchar_t* s = nullptr;
|
||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr, error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
reinterpret_cast<LPWSTR>(&s), 0, nullptr);
|
||||
nullptr, error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
reinterpret_cast<LPWSTR>(&s), 0, nullptr);
|
||||
String str(s);
|
||||
LocalFree(s);
|
||||
return str;
|
||||
@@ -72,11 +74,11 @@ static bool CreateEndPointFromAddr(sockaddr* addr, NetworkEndPoint& endPoint)
|
||||
LOG(Error, "Unable to create endpoint, sockaddr must be INET or INET6! Family : {0}", addr->sa_family);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
if (inet_ntop(addr->sa_family, paddr, ip, INET6_ADDRSTRLEN) == nullptr)
|
||||
{
|
||||
LOG(Error, "Unable to extract address from sockaddr! Error : {0}", GetLastErrorMessage().Get());
|
||||
LOG(Error, "Unable to extract address from sockaddr! Error : {0}", GetLastErrorMessage());
|
||||
return true;
|
||||
}
|
||||
endPoint.Address = String(ip);
|
||||
@@ -107,7 +109,7 @@ static void PrintAddrFromInfo(addrinfoW& info)
|
||||
|
||||
char str[INET6_ADDRSTRLEN];
|
||||
inet_ntop(curr->ai_family, addr, str, INET6_ADDRSTRLEN);
|
||||
LOG(Info, "ADDR INFO family : {0} socktype : {1}, proto : {2} address : {3}", curr->ai_family, curr->ai_socktype, curr->ai_protocol, StringAnsi(str).ToString().Get());
|
||||
LOG(Info, "ADDR INFO family : {0} socktype : {1}, proto : {2} address : {3}", curr->ai_family, curr->ai_socktype, curr->ai_protocol, StringAnsi(str).ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,21 +117,21 @@ static void TranslateSockOptToNative(NetworkSocketOption option, int32* level, i
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
SOCKOPT(NetworkSocketOption::Debug, SOL_SOCKET, SO_DEBUG)
|
||||
SOCKOPT(NetworkSocketOption::ReuseAddr, SOL_SOCKET, SO_REUSEADDR)
|
||||
SOCKOPT(NetworkSocketOption::KeepAlive, SOL_SOCKET, SO_KEEPALIVE)
|
||||
SOCKOPT(NetworkSocketOption::DontRoute, SOL_SOCKET, SO_DONTROUTE)
|
||||
SOCKOPT(NetworkSocketOption::Broadcast, SOL_SOCKET, SO_BROADCAST)
|
||||
SOCKOPT(NetworkSocketOption::UseLoopback, SOL_SOCKET, SO_USELOOPBACK)
|
||||
SOCKOPT(NetworkSocketOption::Linger, SOL_SOCKET, SO_LINGER)
|
||||
SOCKOPT(NetworkSocketOption::OOBInline, SOL_SOCKET, SO_OOBINLINE)
|
||||
SOCKOPT(NetworkSocketOption::SendBuffer, SOL_SOCKET, SO_SNDBUF)
|
||||
SOCKOPT(NetworkSocketOption::RecvBuffer, SOL_SOCKET, SO_RCVBUF)
|
||||
SOCKOPT(NetworkSocketOption::SendTimeout, SOL_SOCKET, SO_SNDTIMEO)
|
||||
SOCKOPT(NetworkSocketOption::RecvTimeout, SOL_SOCKET, SO_RCVTIMEO)
|
||||
SOCKOPT(NetworkSocketOption::Error, SOL_SOCKET, SO_ERROR)
|
||||
SOCKOPT(NetworkSocketOption::NoDelay, IPPROTO_TCP, TCP_NODELAY)
|
||||
SOCKOPT(NetworkSocketOption::IPv6Only, IPPROTO_IPV6, IPV6_V6ONLY)
|
||||
SOCKOPT(NetworkSocketOption::Debug, SOL_SOCKET, SO_DEBUG)
|
||||
SOCKOPT(NetworkSocketOption::ReuseAddr, SOL_SOCKET, SO_REUSEADDR)
|
||||
SOCKOPT(NetworkSocketOption::KeepAlive, SOL_SOCKET, SO_KEEPALIVE)
|
||||
SOCKOPT(NetworkSocketOption::DontRoute, SOL_SOCKET, SO_DONTROUTE)
|
||||
SOCKOPT(NetworkSocketOption::Broadcast, SOL_SOCKET, SO_BROADCAST)
|
||||
SOCKOPT(NetworkSocketOption::UseLoopback, SOL_SOCKET, SO_USELOOPBACK)
|
||||
SOCKOPT(NetworkSocketOption::Linger, SOL_SOCKET, SO_LINGER)
|
||||
SOCKOPT(NetworkSocketOption::OOBInline, SOL_SOCKET, SO_OOBINLINE)
|
||||
SOCKOPT(NetworkSocketOption::SendBuffer, SOL_SOCKET, SO_SNDBUF)
|
||||
SOCKOPT(NetworkSocketOption::RecvBuffer, SOL_SOCKET, SO_RCVBUF)
|
||||
SOCKOPT(NetworkSocketOption::SendTimeout, SOL_SOCKET, SO_SNDTIMEO)
|
||||
SOCKOPT(NetworkSocketOption::RecvTimeout, SOL_SOCKET, SO_RCVTIMEO)
|
||||
SOCKOPT(NetworkSocketOption::Error, SOL_SOCKET, SO_ERROR)
|
||||
SOCKOPT(NetworkSocketOption::NoDelay, IPPROTO_TCP, TCP_NODELAY)
|
||||
SOCKOPT(NetworkSocketOption::IPv6Only, IPPROTO_IPV6, IPV6_V6ONLY)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,14 +146,14 @@ bool Win32Network::CreateSocket(NetworkSocket& socket, NetworkProtocolType proto
|
||||
|
||||
if ((sock = ::socket(family, stype, prot)) == INVALID_SOCKET)
|
||||
{
|
||||
LOG(Error, "Can't create native socket! Error : {0}", GetLastErrorMessage().Get());
|
||||
LOG(Error, "Can't create native socket! Error : {0}", GetLastErrorMessage());
|
||||
return true;
|
||||
}
|
||||
memcpy(socket.Data, &sock, sizeof sock);
|
||||
unsigned long value = 1;
|
||||
if (ioctlsocket(sock, FIONBIO, &value) == SOCKET_ERROR)
|
||||
{
|
||||
LOG(Error, "Can't set socket to NON-BLOCKING type! Error : {0}", GetLastErrorMessage().Get());
|
||||
LOG(Error, "Can't set socket to NON-BLOCKING type! Error : {0}", GetLastErrorMessage());
|
||||
return true; // Support using blocking socket , need to test it
|
||||
}
|
||||
return false;
|
||||
@@ -181,10 +183,10 @@ bool Win32Network::SetSocketOption(NetworkSocket& socket, NetworkSocketOption op
|
||||
int32 optnme = 0;
|
||||
|
||||
TranslateSockOptToNative(option, &optlvl, &optnme);
|
||||
|
||||
|
||||
if (setsockopt(*(SOCKET*)socket.Data, optlvl, optnme, (char*)&value, sizeof value) == SOCKET_ERROR)
|
||||
{
|
||||
LOG(Warning, "Unable to set socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage().Get());
|
||||
LOG(Warning, "Unable to set socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -202,13 +204,13 @@ bool Win32Network::GetSocketOption(NetworkSocket& socket, NetworkSocketOption op
|
||||
{
|
||||
int32 optlvl = 0;
|
||||
int32 optnme = 0;
|
||||
|
||||
|
||||
TranslateSockOptToNative(option, &optlvl, &optnme);
|
||||
|
||||
|
||||
int32 size;
|
||||
if (getsockopt(*(SOCKET*)socket.Data, optlvl, optnme, (char*)value, &size) == SOCKET_ERROR)
|
||||
{
|
||||
LOG(Warning, "Unable to get socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage().Get());
|
||||
LOG(Warning, "Unable to get socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -222,7 +224,7 @@ bool Win32Network::ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoin
|
||||
int error = WSAGetLastError();
|
||||
if (error == WSAEWOULDBLOCK)
|
||||
return false;
|
||||
LOG(Error, "Unable to connect socket to address! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address.Get(), endPoint.Port.Get(), GetErrorMessage(error).Get());
|
||||
LOG(Error, "Unable to connect socket to address! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address, endPoint.Port, GetErrorMessage(error));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -239,7 +241,7 @@ bool Win32Network::BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint)
|
||||
const uint16 size = endPoint.IPVersion == NetworkIPVersion::IPv6 ? sizeof sockaddr_in6 : sizeof sockaddr_in;
|
||||
if (bind(*(SOCKET*)socket.Data, (const sockaddr*)endPoint.Data, size) == SOCKET_ERROR)
|
||||
{
|
||||
LOG(Error, "Unable to bind socket! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address.Get(), endPoint.Port.Get(), GetLastErrorMessage().Get());
|
||||
LOG(Error, "Unable to bind socket! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address, endPoint.Port, GetLastErrorMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -249,7 +251,7 @@ bool Win32Network::Listen(NetworkSocket& socket, uint16 queueSize)
|
||||
{
|
||||
if (listen(*(SOCKET*)socket.Data, (int32)queueSize) == SOCKET_ERROR)
|
||||
{
|
||||
LOG(Error, "Unable to listen ! Socket : {0} Error : {1}", GetLastErrorMessage().Get());
|
||||
LOG(Error, "Unable to listen ! Socket : {0} Error : {1}", GetLastErrorMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -270,7 +272,7 @@ bool Win32Network::Accept(NetworkSocket& serverSock, NetworkSocket& newSock, Net
|
||||
int32 error = WSAGetLastError();
|
||||
if (error == WSAEWOULDBLOCK)
|
||||
return false;
|
||||
LOG(Warning, "Unable to accept incoming connection! Socket : {0} Error : {1}", *(SOCKET*)serverSock.Data, GetErrorMessage(error).Get());
|
||||
LOG(Warning, "Unable to accept incoming connection! Socket : {0} Error : {1}", *(SOCKET*)serverSock.Data, GetErrorMessage(error));
|
||||
return true;
|
||||
}
|
||||
memcpy(newSock.Data, &sock, sizeof sock);
|
||||
@@ -292,7 +294,7 @@ bool Win32Network::IsReadable(NetworkSocket& socket)
|
||||
int32 error = WSAGetLastError();
|
||||
if (error == WSAEWOULDBLOCK)
|
||||
return false;
|
||||
LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error).Get());
|
||||
LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error));
|
||||
return false;
|
||||
}
|
||||
if (entry.revents & POLLRDNORM)
|
||||
@@ -310,7 +312,7 @@ bool Win32Network::IsWriteable(NetworkSocket& socket)
|
||||
int32 error = WSAGetLastError();
|
||||
if (error == WSAEWOULDBLOCK)
|
||||
return false;
|
||||
LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error).Get());
|
||||
LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error));
|
||||
return false;
|
||||
}
|
||||
if (entry.revents & POLLWRNORM)
|
||||
@@ -322,7 +324,7 @@ int32 Win32Network::Poll(NetworkSocketGroup& group)
|
||||
{
|
||||
int32 pollret = WSAPoll((pollfd*)group.Data, group.Count, 0);
|
||||
if (pollret == SOCKET_ERROR)
|
||||
LOG(Error, "Unable to poll socket group! Error : {0}", GetLastErrorMessage().Get());
|
||||
LOG(Error, "Unable to poll socket group! Error : {0}", GetLastErrorMessage());
|
||||
return pollret;
|
||||
}
|
||||
|
||||
@@ -354,7 +356,7 @@ int32 Win32Network::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& s
|
||||
pollinfo.events = POLLRDNORM | POLLWRNORM;
|
||||
*(pollfd*)&group.Data[group.Count * SOCKGROUP_ITEMSIZE] = pollinfo;
|
||||
group.Count++;
|
||||
return group.Count-1;
|
||||
return group.Count - 1;
|
||||
}
|
||||
|
||||
void Win32Network::ClearGroup(NetworkSocketGroup& group)
|
||||
@@ -374,7 +376,7 @@ int32 Win32Network::WriteSocket(NetworkSocket socket, byte* data, uint32 length,
|
||||
{
|
||||
if ((size = send(*(SOCKET*)socket.Data, (const char*)data, length, 0)) == SOCKET_ERROR)
|
||||
{
|
||||
LOG(Error, "Unable to send data! Socket : {0} Data Length : {1} Error : {2}", *(SOCKET*)socket.Data, length, GetLastErrorMessage().Get());
|
||||
LOG(Error, "Unable to send data! Socket : {0} Data Length : {1} Error : {2}", *(SOCKET*)socket.Data, length, GetLastErrorMessage());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -382,13 +384,13 @@ int32 Win32Network::WriteSocket(NetworkSocket socket, byte* data, uint32 length,
|
||||
{
|
||||
if ((size = sendto(*(SOCKET*)socket.Data, (const char*)data, length, 0, (const sockaddr*)endPoint->Data, GetAddrSizeFromEP(*endPoint))) == SOCKET_ERROR)
|
||||
{
|
||||
LOG(Error, "Unable to send data! Socket : {0} Address : {1} Port : {2} Data Length : {3} Error : {4}", *(SOCKET*)socket.Data, endPoint->Address, endPoint->Port, length, GetLastErrorMessage().Get());
|
||||
LOG(Error, "Unable to send data! Socket : {0} Address : {1} Port : {2} Data Length : {3} Error : {4}", *(SOCKET*)socket.Data, endPoint->Address, endPoint->Port, length, GetLastErrorMessage());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: better explanation
|
||||
// TODO: better explanation
|
||||
LOG(Error, "Unable to send data! Socket : {0} Data Length : {1}", *(SOCKET*)socket.Data, length);
|
||||
return -1;
|
||||
}
|
||||
@@ -405,7 +407,7 @@ int32 Win32Network::ReadSocket(NetworkSocket socket, byte* buffer, uint32 buffer
|
||||
const int32 error = WSAGetLastError();
|
||||
if (error == WSAEWOULDBLOCK)
|
||||
return 0;
|
||||
LOG(Error, "Unable to read data! Socket : {0} Buffer Size : {1} Error : {2}", *(SOCKET*)socket.Data, bufferSize, GetErrorMessage(error).Get());
|
||||
LOG(Error, "Unable to read data! Socket : {0} Buffer Size : {1} Error : {2}", *(SOCKET*)socket.Data, bufferSize, GetErrorMessage(error));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -415,7 +417,7 @@ int32 Win32Network::ReadSocket(NetworkSocket socket, byte* buffer, uint32 buffer
|
||||
sockaddr_in6 addr;
|
||||
if ((size = recvfrom(*(SOCKET*)socket.Data, (char*)buffer, bufferSize, 0, (sockaddr*)&addr, &addrsize)) == SOCKET_ERROR)
|
||||
{
|
||||
LOG(Error, "Unable to read data! Socket : {0} Buffer Size : {1} Error : {2}", *(SOCKET*)socket.Data, bufferSize, GetLastErrorMessage().Get());
|
||||
LOG(Error, "Unable to read data! Socket : {0} Buffer Size : {1} Error : {2}", *(SOCKET*)socket.Data, bufferSize, GetLastErrorMessage());
|
||||
return -1;
|
||||
}
|
||||
if (CreateEndPointFromAddr((sockaddr*)&addr, *endPoint))
|
||||
@@ -439,13 +441,13 @@ bool Win32Network::CreateEndPoint(String* address, String* port, NetworkIPVersio
|
||||
// consider using NUMERICHOST/NUMERICSERV if address is a valid Ipv4 or IPv6 so we can skip some look up ( potentially slow when resolving host names )
|
||||
if ((status = GetAddrInfoW(address == nullptr ? nullptr : address->Get(), port->Get(), &hints, &info)) != 0)
|
||||
{
|
||||
LOG(Error, "Unable to query info for address : {0} Error : {1}", address != nullptr ? address->Get() : String("ANY").Get(), gai_strerror(status));
|
||||
LOG(Error, "Unable to query info for address : {0} Error : {1}", address ? address->Get() : String("ANY"), gai_strerror(status));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (info == nullptr)
|
||||
{
|
||||
LOG(Error, "Unable to resolve address! Address : {0}", address != nullptr ? address->Get() : String("ANY").Get());
|
||||
LOG(Error, "Unable to resolve address! Address : {0}", address ? address->Get() : String("ANY"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,9 @@
|
||||
#include "Engine/Core/Types/Guid.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#include "Engine/Core/Math/Math.h"
|
||||
#include "IncludeWindowsHeaders.h"
|
||||
#include "Engine/Core/Collections/HashFunctions.h"
|
||||
#include "Engine/Platform/Network.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "IncludeWindowsHeaders.h"
|
||||
|
||||
#include <Psapi.h>
|
||||
#include <WinSock2.h>
|
||||
@@ -27,10 +26,9 @@ namespace
|
||||
CPUInfo CpuInfo;
|
||||
uint64 ClockFrequency;
|
||||
double CyclesToSeconds;
|
||||
WSAData WsaData;
|
||||
}
|
||||
|
||||
static WSAData _wsaData;
|
||||
|
||||
// Helper function to count set bits in the processor mask
|
||||
DWORD CountSetBits(ULONG_PTR bitMask)
|
||||
{
|
||||
@@ -52,9 +50,9 @@ static String GetLastErrorMessage()
|
||||
{
|
||||
wchar_t* s = nullptr;
|
||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr, WSAGetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
reinterpret_cast<LPWSTR>(&s), 0, nullptr);
|
||||
nullptr, WSAGetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
reinterpret_cast<LPWSTR>(&s), 0, nullptr);
|
||||
String str(s);
|
||||
LocalFree(s);
|
||||
return str;
|
||||
@@ -72,6 +70,7 @@ bool Win32Platform::Init()
|
||||
ClockFrequency = frequency.QuadPart;
|
||||
CyclesToSeconds = 1.0 / static_cast<double>(frequency.QuadPart);
|
||||
|
||||
// Count CPUs
|
||||
BOOL done = FALSE;
|
||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = nullptr;
|
||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr;
|
||||
@@ -84,12 +83,10 @@ bool Win32Platform::Init()
|
||||
DWORD processorPackageCount = 0;
|
||||
DWORD byteOffset = 0;
|
||||
PCACHE_DESCRIPTOR cache;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
DWORD rc = GetLogicalProcessorInformation(buffer, &returnLength);
|
||||
|
||||
if (FALSE == rc)
|
||||
if (rc == FALSE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
@@ -97,9 +94,7 @@ bool Win32Platform::Init()
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
buffer = static_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION>(malloc(returnLength));
|
||||
|
||||
if (buffer == nullptr)
|
||||
{
|
||||
return true;
|
||||
@@ -115,23 +110,16 @@ bool Win32Platform::Init()
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = buffer;
|
||||
|
||||
while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength)
|
||||
{
|
||||
switch (ptr->Relationship)
|
||||
{
|
||||
case RelationProcessorCore:
|
||||
|
||||
processorCoreCount++;
|
||||
|
||||
// A hyper threaded core supplies more than one logical processor
|
||||
logicalProcessorCount += CountSetBits(ptr->ProcessorMask);
|
||||
break;
|
||||
|
||||
case RelationCache:
|
||||
// Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.
|
||||
cache = &ptr->Cache;
|
||||
if (cache->Level == 1)
|
||||
{
|
||||
@@ -146,9 +134,7 @@ bool Win32Platform::Init()
|
||||
processorL3CacheSize += cache->Size;
|
||||
}
|
||||
break;
|
||||
|
||||
case RelationProcessorPackage:
|
||||
// Logical processors share a physical package
|
||||
processorPackageCount++;
|
||||
break;
|
||||
}
|
||||
@@ -228,8 +214,10 @@ bool Win32Platform::Init()
|
||||
DeviceId.D = (uint32)cpuInfo.ClockSpeed * cpuInfo.LogicalProcessorCount * cpuInfo.ProcessorCoreCount * cpuInfo.CacheLineSize;
|
||||
}
|
||||
|
||||
if (WSAStartup(MAKEWORD(2, 0), &_wsaData) != 0)
|
||||
LOG(Error, "Unable to initializes native network! Error : {0}", GetLastErrorMessage().Get());
|
||||
// Init networking
|
||||
if (WSAStartup(MAKEWORD(2, 0), &WsaData) != 0)
|
||||
LOG(Error, "Unable to initializes native network! Error : {0}", GetLastErrorMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -240,19 +228,8 @@ void Win32Platform::Exit()
|
||||
|
||||
void Win32Platform::MemoryBarrier()
|
||||
{
|
||||
// NOTE: _ReadWriteBarrier and friends only prevent the
|
||||
// compiler from reordering loads and stores. To prevent
|
||||
// the CPU from doing the same, we have to use the
|
||||
// MemoryBarrier macro which expands to e.g. a serializing
|
||||
// XCHG instruction on x86. Also note that the MemoryBarrier
|
||||
// macro does *not* imply _ReadWriteBarrier, so that call
|
||||
// cannot be eliminated.
|
||||
|
||||
_ReadWriteBarrier();
|
||||
|
||||
// MemoryBarrier macro (we use undef to hide some symbols from Windows headers)
|
||||
#if PLATFORM_64BITS
|
||||
|
||||
#ifdef _AMD64_
|
||||
__faststorefence();
|
||||
#elif defined(_IA64_)
|
||||
@@ -260,7 +237,6 @@ void Win32Platform::MemoryBarrier()
|
||||
#else
|
||||
#error "Invalid platform."
|
||||
#endif
|
||||
|
||||
#else
|
||||
LONG barrier;
|
||||
__asm {
|
||||
|
||||
Reference in New Issue
Block a user