#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX) #include "net/connection/WowConnectionNet.hpp" #include "net/connection/WowConnection.hpp" #include #include #include #include #include #include #include #include #include int32_t s_workerPipe[2]; void WowConnectionNet::PlatformAdd(WowConnection* connection) { uint32_t on = 1; setsockopt(connection->m_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); char buf = '\1'; write(s_workerPipe[1], &buf, sizeof(buf)); } void WowConnectionNet::PlatformChangeState(WowConnection* connection, WOW_CONN_STATE state) { char buf = '\1'; write(s_workerPipe[1], &buf, sizeof(buf)); } void WowConnectionNet::PlatformInit(bool useEngine) { // TODO } void WowConnectionNet::PlatformRun() { pipe(s_workerPipe); if (fcntl(s_workerPipe[0], F_SETFL, O_NONBLOCK) < 0) { perror("fcntl(worker pipe)"); } TSGrowableArray connections; char buf[25]; while (!this->m_stop) { timeval timeout = { 30, 0 }; fd_set readFds = {}; fd_set writeFds = {}; fd_set errorFds = {}; readFds.fds_bits[s_workerPipe[0] >> 5] |= 1 << (s_workerPipe[0] & 0x1F); auto fdCount = s_workerPipe[0]; int32_t v39 = 0; int32_t v41 = 0; this->m_connectionsLock.Enter(); for (auto connection = this->m_connections.Head(); connection; connection = this->m_connections.Link(connection)->Next()) { if (connection->m_serviceCount) { continue; } switch (connection->m_connState) { case WOWC_CONNECTING: { errorFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F); writeFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F); connections.Add(1, &connection); connection->AddRef(); fdCount = std::max(fdCount, connection->m_sock); break; } case WOWC_LISTENING: { readFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F); connections.Add(1, &connection); connection->AddRef(); fdCount = std::max(fdCount, connection->m_sock); break; } case WOWC_CONNECTED: { readFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F); errorFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F); // TODO connections.Add(1, &connection); connection->AddRef(); fdCount = std::max(fdCount, connection->m_sock); } case WOWC_DISCONNECTING: { // TODO v41++; connections.Add(1, &connection); connection->AddRef(); break; } default: { break; } } } this->m_connectionsLock.Leave(); if (v41 > 0) { timeout = { 0, 0 }; } if (connections.Count() > 0) { // TODO } select(fdCount + 1, &readFds, &writeFds, &errorFds, &timeout); auto v1 = s_workerPipe[0]; if (((1 << (s_workerPipe[0] & 0x1F)) & readFds.fds_bits[s_workerPipe[0] >> 5]) != 0) { while (read(v1, buf, 1u) > 0) { v1 = s_workerPipe[0]; } } for (int32_t i = 0; i < connections.Count(); i++) { auto connection = connections[i]; uint32_t signalFlags = 0x0; if (!(connection->m_sock & 0x80000000)) { if (FD_ISSET(connection->m_sock, &writeFds)) { signalFlags |= 0x1; } if (FD_ISSET(connection->m_sock, &readFds)) { signalFlags |= 0x2; } if (FD_ISSET(connection->m_sock, &errorFds)) { signalFlags |= 0x4; } } if (connection->m_connState == WOWC_DISCONNECTING) { signalFlags |= 0x8; } // TODO // auto v15 = connection->dword10C; // if (!(v15 & 1) && v15) { // signalFlags |= 0x2; // } if (signalFlags) { this->SignalWorker(connection, signalFlags); } connection->Release(); } } } void WowConnectionNet::PlatformWorkerReady() { char buf = '\1'; write(s_workerPipe[1], &buf, sizeof(buf)); } #endif