diff --git a/Server/src/server.cpp b/Server/src/server.cpp index 950c51a..7af71ed 100644 --- a/Server/src/server.cpp +++ b/Server/src/server.cpp @@ -59,7 +59,7 @@ int main() { bool enable = true; clientSock.setsockopt(SOL_SOCKET, SO_KEEPALIVE, (const char *)&enable, sizeof(enable)); Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; - ZeroMemory(&ptr->overlapped, sizeof(OVERLAPPED)); + ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); ptr->socket = std::move(clientSock); ptr->recvbytes = ptr->sendbytes = 0; ptr->wsabuf.buf = ptr->buf; @@ -67,7 +67,7 @@ int main() { iocp.registerSocket(ptr->socket.sock); - int returnData = WSARecv(ptr->socket.sock, &ptr->wsabuf, 1, &recvbytes, &flags, &ptr->overlapped, NULL); + int returnData = iocp.recv(ptr); } } diff --git a/impl/Socket/IOCP.cpp b/impl/Socket/IOCP.cpp index 1ccf258..80356e2 100644 --- a/impl/Socket/IOCP.cpp +++ b/impl/Socket/IOCP.cpp @@ -15,10 +15,14 @@ void IOCP::registerSocket(SOCKET sock) { #endif } -int IOCP::recv(void* __restrict __buf, size_t __n, int __flags) { +int IOCP::recv(Chattr::IOCPPASSINDATA* data) { + DWORD recvbytes = 0, flags = 0; + return ::WSARecv(data->socket.sock, &data->wsabuf, 1, &recvbytes, &flags, &data->overlapped, NULL); } -int IOCP::send(const void* __buf, size_t __n, int __flags) { +int IOCP::send(Chattr::IOCPPASSINDATA* data, int __flags) { + DWORD sendbytes = 0; + return ::WSASend(data->socket.sock, &data->wsabuf, 1, &sendbytes, __flags, &data->overlapped, NULL); } } \ No newline at end of file diff --git a/include/Socket/IOCP.hpp b/include/Socket/IOCP.hpp index 3db141e..9129dcb 100644 --- a/include/Socket/IOCP.hpp +++ b/include/Socket/IOCP.hpp @@ -7,6 +7,12 @@ namespace Chattr { +#ifndef _WIN32 +typedef struct _OVERLAPPED { + char dummy; +} OVERLAPPED; +#endif + struct IOCPPASSINDATA { OVERLAPPED overlapped; TCPSocket socket; @@ -18,6 +24,7 @@ struct IOCPPASSINDATA { class IOCP { public: +#ifdef _WIN32 static void iocpWather(ThreadPool* threadPool, HANDLE completionPort_, std::function callback) { DWORD tid = GetCurrentThreadId(); spdlog::debug("Waiting IO to complete on TID: {}.", tid); @@ -34,6 +41,24 @@ public: threadPool->enqueueJob(callback, data); threadPool->enqueueJob(iocpWather, completionPort_, callback); }; +#elif __linux__ + static void iocpWather(ThreadPool* threadPool, HANDLE completionPort_, std::function callback) { + DWORD tid = GetCurrentThreadId(); + spdlog::debug("Waiting IO to complete on TID: {}.", tid); + IOCPPASSINDATA* data; + SOCKET sock; + DWORD cbTransfrred; + int retVal = GetQueuedCompletionStatus(completionPort_, &cbTransfrred, (PULONG_PTR)&sock, (LPOVERLAPPED*)&data, INFINITE); + if (retVal == 0 || cbTransfrred == 0) { + spdlog::info("Client disconnected. [{}]", (std::string)(data->socket.remoteAddr)); + delete data; + threadPool->enqueueJob(iocpWather, completionPort_, callback); + return; + } + threadPool->enqueueJob(callback, data); + threadPool->enqueueJob(iocpWather, completionPort_, callback); + }; +#endif template void init(ThreadPool* __IOCPThread, _Callable&& callback) { @@ -42,10 +67,12 @@ public: completionPort_ = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); if (completionPort_ == NULL) log::critical("CreateIoCompletionPort()"); +#elif __linux__ +#endif auto boundFunc = [callback = std::move(callback)](ThreadPool* __IOCPThread, IOCPPASSINDATA* data) mutable { callback(__IOCPThread, data); - }; + }; int tCount = __IOCPThread->threadCount; @@ -58,15 +85,12 @@ public: std::function task(boundFunc); __IOCPThread->enqueueJob(iocpWather, completionPort_, task); } -#elif __linux__ - -#endif } void registerSocket(SOCKET sock); - int recv(void* __restrict __buf, size_t __n, int __flags); - int send(const void* __buf, size_t __n, int __flags); + int recv(Chattr::IOCPPASSINDATA* data); + int send(Chattr::IOCPPASSINDATA* data, int __flags); private: struct Chattr::WSAManager wsaManager;