mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-04-16 01:55:21 +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_readBufferSize = 0;
|
||||
|
||||
this->m_event = nullptr;
|
||||
|
||||
// TODO
|
||||
|
||||
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);
|
||||
|
||||
#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)
|
||||
if (this->m_sendList.Head()) {
|
||||
// TODO
|
||||
@ -697,11 +712,15 @@ void WowConnection::StartConnect() {
|
||||
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);
|
||||
|
||||
uint32_t opt = 1;
|
||||
setsockopt(this->m_sock, SOL_SOCKET, 4130, &opt, sizeof(opt));
|
||||
#endif
|
||||
|
||||
sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
@ -720,11 +739,19 @@ void WowConnection::StartConnect() {
|
||||
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) {
|
||||
this->m_lock.Leave();
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
WowConnection::s_network->Remove(this);
|
||||
this->CloseSocket(this->m_sock);
|
||||
@ -733,5 +760,4 @@ void WowConnection::StartConnect() {
|
||||
this->SetState(WOWC_ERROR);
|
||||
|
||||
this->m_lock.Leave();
|
||||
#endif
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ class WowConnection {
|
||||
TSLink<WowConnection> m_netlink;
|
||||
SCritSect m_lock;
|
||||
ATOMIC32 m_serviceCount;
|
||||
void* m_event;
|
||||
WOWC_TYPE m_type;
|
||||
|
||||
// Member functions
|
||||
|
@ -29,6 +29,7 @@ class WowConnectionNet {
|
||||
STORM_EXPLICIT_LIST(WowConnection, m_netlink) m_connections;
|
||||
SSemaphore m_workerSem;
|
||||
void (*m_threadinit)();
|
||||
void* event8E8;
|
||||
|
||||
// Member functions
|
||||
WowConnectionNet(uint32_t numThreads, void (*threadinit)())
|
||||
|
@ -1,25 +1,151 @@
|
||||
#include "net/connection/WowConnectionNet.hpp"
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
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) {
|
||||
// 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) {
|
||||
// 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) {
|
||||
// TODO
|
||||
SetEvent(this->event8E8);
|
||||
}
|
||||
|
||||
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() {
|
||||
// TODO
|
||||
SetEvent(this->event8E8);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user