mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-04-18 11:02:44 +03:00
feat(net): finish basic networking support for windows
This commit is contained in:
parent
b537c34990
commit
497520e672
@ -590,6 +590,8 @@ void WowConnection::Init(WowConnectionResponse* response, void (*func)(void)) {
|
|||||||
this->m_readBytes = 0;
|
this->m_readBytes = 0;
|
||||||
this->m_readBufferSize = 0;
|
this->m_readBufferSize = 0;
|
||||||
|
|
||||||
|
this->m_event = nullptr;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
this->SetState(WOWC_INITIALIZED);
|
this->SetState(WOWC_INITIALIZED);
|
||||||
@ -635,7 +637,20 @@ WC_SEND_RESULT WowConnection::SendRaw(uint8_t* data, int32_t len, bool a4) {
|
|||||||
STORM_ASSERT(this->m_sock >= 0);
|
STORM_ASSERT(this->m_sock >= 0);
|
||||||
|
|
||||||
#if defined (WHOA_SYSTEM_WIN)
|
#if defined (WHOA_SYSTEM_WIN)
|
||||||
// TODO
|
if (this->m_sendList.Head()) {
|
||||||
|
// TODO
|
||||||
|
} else {
|
||||||
|
auto written = send(this->m_sock, reinterpret_cast<char*>(data), len, 0x0);
|
||||||
|
|
||||||
|
if (written == len) {
|
||||||
|
this->m_lock.Leave();
|
||||||
|
return WC_SEND_SENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (written < 0) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
if (this->m_sendList.Head()) {
|
if (this->m_sendList.Head()) {
|
||||||
// TODO
|
// TODO
|
||||||
@ -697,11 +712,15 @@ void WowConnection::StartConnect() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WHOA_SYSTEM_MAC)
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
u_long argp = 1;
|
||||||
|
ioctlsocket(this->m_sock, FIONBIO, &argp);
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC)
|
||||||
fcntl(this->m_sock, F_SETFL, O_NONBLOCK);
|
fcntl(this->m_sock, F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
uint32_t opt = 1;
|
uint32_t opt = 1;
|
||||||
setsockopt(this->m_sock, SOL_SOCKET, 4130, &opt, sizeof(opt));
|
setsockopt(this->m_sock, SOL_SOCKET, 4130, &opt, sizeof(opt));
|
||||||
|
#endif
|
||||||
|
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
@ -720,11 +739,19 @@ void WowConnection::StartConnect() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
if (WSAGetLastError() == WSAEWOULDBLOCK) {
|
||||||
|
this->m_lock.Leave();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC)
|
||||||
if (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS) {
|
if (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS) {
|
||||||
this->m_lock.Leave();
|
this->m_lock.Leave();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
WowConnection::s_network->Remove(this);
|
WowConnection::s_network->Remove(this);
|
||||||
this->CloseSocket(this->m_sock);
|
this->CloseSocket(this->m_sock);
|
||||||
@ -733,5 +760,4 @@ void WowConnection::StartConnect() {
|
|||||||
this->SetState(WOWC_ERROR);
|
this->SetState(WOWC_ERROR);
|
||||||
|
|
||||||
this->m_lock.Leave();
|
this->m_lock.Leave();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ class WowConnection {
|
|||||||
TSLink<WowConnection> m_netlink;
|
TSLink<WowConnection> m_netlink;
|
||||||
SCritSect m_lock;
|
SCritSect m_lock;
|
||||||
ATOMIC32 m_serviceCount;
|
ATOMIC32 m_serviceCount;
|
||||||
|
void* m_event;
|
||||||
WOWC_TYPE m_type;
|
WOWC_TYPE m_type;
|
||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
|
@ -29,6 +29,7 @@ class WowConnectionNet {
|
|||||||
STORM_EXPLICIT_LIST(WowConnection, m_netlink) m_connections;
|
STORM_EXPLICIT_LIST(WowConnection, m_netlink) m_connections;
|
||||||
SSemaphore m_workerSem;
|
SSemaphore m_workerSem;
|
||||||
void (*m_threadinit)();
|
void (*m_threadinit)();
|
||||||
|
void* event8E8;
|
||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
WowConnectionNet(uint32_t numThreads, void (*threadinit)())
|
WowConnectionNet(uint32_t numThreads, void (*threadinit)())
|
||||||
|
@ -1,25 +1,151 @@
|
|||||||
#include "net/connection/WowConnectionNet.hpp"
|
#include "net/connection/WowConnectionNet.hpp"
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
void WowConnectionNet::PlatformAdd(WowConnection* connection) {
|
void WowConnectionNet::PlatformAdd(WowConnection* connection) {
|
||||||
// TODO
|
if (!connection->m_event) {
|
||||||
|
connection->m_event = WSACreateEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t on = 1;
|
||||||
|
setsockopt(connection->m_sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&on), sizeof(on));
|
||||||
|
|
||||||
|
SetEvent(this->event8E8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WowConnectionNet::PlatformChangeState(WowConnection* connection, WOW_CONN_STATE state) {
|
void WowConnectionNet::PlatformChangeState(WowConnection* connection, WOW_CONN_STATE state) {
|
||||||
// TODO
|
uint32_t networkEvents = 0x0;
|
||||||
|
|
||||||
|
switch (connection->GetState()) {
|
||||||
|
case WOWC_CONNECTING: {
|
||||||
|
networkEvents = FD_CLOSE | FD_CONNECT | FD_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WOWC_LISTENING: {
|
||||||
|
networkEvents = FD_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WOWC_CONNECTED: {
|
||||||
|
// TODO conditional network event
|
||||||
|
networkEvents = FD_CLOSE | FD_READ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connection->m_event && connection->m_sock >= 0) {
|
||||||
|
WSAEventSelect(connection->m_sock, connection->m_event, networkEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetEvent(this->event8E8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WowConnectionNet::PlatformInit(bool useEngine) {
|
void WowConnectionNet::PlatformInit(bool useEngine) {
|
||||||
// TODO
|
WSADATA wsaData;
|
||||||
|
auto err = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
|
if (err || wsaData.wVersion != MAKEWORD(2, 2)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->event8E8 = CreateEvent(nullptr, true, false, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WowConnectionNet::PlatformRemove(WowConnection* connection) {
|
void WowConnectionNet::PlatformRemove(WowConnection* connection) {
|
||||||
// TODO
|
SetEvent(this->event8E8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WowConnectionNet::PlatformRun() {
|
void WowConnectionNet::PlatformRun() {
|
||||||
// TODO
|
uint32_t timeout = 500;
|
||||||
|
|
||||||
|
WowConnection* connections[64];
|
||||||
|
HANDLE connectionEvents[64];
|
||||||
|
|
||||||
|
while (!this->m_stop) {
|
||||||
|
this->m_connectionsLock.Enter();
|
||||||
|
|
||||||
|
uint32_t connectionCount = 0;
|
||||||
|
|
||||||
|
connections[connectionCount] = nullptr;
|
||||||
|
connectionEvents[connectionCount] = this->event8E8;
|
||||||
|
connectionCount++;
|
||||||
|
|
||||||
|
for (auto connection = this->m_connections.Head(); connection; connection = this->m_connections.Next(connection)) {
|
||||||
|
if (connection->m_serviceCount) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (connection->GetState()) {
|
||||||
|
case WOWC_CONNECTING: {
|
||||||
|
WSAEventSelect(connection->m_sock, connection->m_event, FD_CONNECT | FD_CLOSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WOWC_LISTENING: {
|
||||||
|
WSAEventSelect(connection->m_sock, connection->m_event, FD_ACCEPT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WOWC_CONNECTED: {
|
||||||
|
// TODO conditional network event
|
||||||
|
WSAEventSelect(connection->m_sock, connection->m_event, FD_CONNECT | FD_READ);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WOWC_DISCONNECTED: {
|
||||||
|
timeout = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectionCount < 64) {
|
||||||
|
connection->AddRef();
|
||||||
|
|
||||||
|
connections[connectionCount] = connection;
|
||||||
|
connectionEvents[connectionCount] = connection->m_event;
|
||||||
|
connectionCount++;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_connectionsLock.Leave();
|
||||||
|
|
||||||
|
auto waitIndex = WaitForMultipleObjects(connectionCount, connectionEvents, false, timeout);
|
||||||
|
|
||||||
|
if (waitIndex == 0) {
|
||||||
|
ResetEvent(connectionEvents[0]);
|
||||||
|
} else {
|
||||||
|
for (uint32_t i = 1; i < connectionCount; i++) {
|
||||||
|
WSANETWORKEVENTS networkEvents;
|
||||||
|
WSAEnumNetworkEvents(connections[i]->m_sock, connectionEvents[i], &networkEvents);
|
||||||
|
|
||||||
|
uint32_t signalFlags = 0x0;
|
||||||
|
if (networkEvents.lNetworkEvents & (FD_CLOSE | FD_ACCEPT | FD_READ)) {
|
||||||
|
signalFlags |= 0x2;
|
||||||
|
}
|
||||||
|
if (networkEvents.lNetworkEvents & (FD_CLOSE | FD_CONNECT | FD_WRITE)) {
|
||||||
|
signalFlags |= 0x1;
|
||||||
|
}
|
||||||
|
if (connections[i]->m_connState == WOWC_DISCONNECTING) {
|
||||||
|
signalFlags |= 0x8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO timeout manipulation
|
||||||
|
|
||||||
|
if (signalFlags) {
|
||||||
|
this->SignalWorker(connections[i], signalFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 1; i < connectionCount; i++) {
|
||||||
|
connections[i]->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WowConnectionNet::PlatformWorkerReady() {
|
void WowConnectionNet::PlatformWorkerReady() {
|
||||||
// TODO
|
SetEvent(this->event8E8);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user