#include "socket/iocp.h" #include "utils/thread_pool.h" namespace Socket { IOCP::IOCP() {} IOCP::~IOCP() { destruct(); } void IOCP::destruct() { #ifdef __linux__ uint64_t u = 1; ::write(epollDetroyerFd, &u, sizeof(uint64_t)); close(epollfd_); #endif } void IOCP::registerSocket(IOCPPASSINDATA* data) { data->event = IOCPEVENT::READ; #ifdef _WIN32 HANDLE returnData = ::CreateIoCompletionPort( (HANDLE)data->socket->sock, completionPort_, data->socket->sock, 0); if (returnData == 0) completionPort_ = returnData; #elif __linux__ int flags = ::fcntl(data->socket->sock, F_GETFL); flags |= O_NONBLOCK; fcntl(data->socket->sock, F_SETFL, flags); struct epoll_event ev; ev.events = EPOLLIN | EPOLLONESHOT; data->sendQueue = std::make_shared>(); ev.data.ptr = data; int rc = epoll_ctl(epollfd_, EPOLL_CTL_ADD, data->socket->sock, &ev); if (rc < 0) log::critical("epoll_ctl()"); #endif } int IOCP::recv(IOCPPASSINDATA* data, int bufferCount) { data->event = IOCPEVENT::READ; #ifdef _WIN32 DWORD recvbytes = 0, flags = 0; return ::WSARecv(data->socket->sock, &data->wsabuf, bufferCount, &recvbytes, &flags, &data->overlapped, NULL); #elif __linux__ struct epoll_event ev; ev.events = EPOLLIN | EPOLLONESHOT; ev.data.ptr = data; return ::epoll_ctl(epollfd_, EPOLL_CTL_MOD, data->socket->sock, &ev); #endif } int IOCP::send(IOCPPASSINDATA* data, int bufferCount, int __flags) { data->event = IOCPEVENT::WRITE; #ifdef _WIN32 DWORD sendbytes = 0; return ::WSASend(data->socket->sock, &data->wsabuf, bufferCount, &sendbytes, __flags, &data->overlapped, NULL); #elif __linux__ struct epoll_event ev; ev.events = EPOLLIN | EPOLLOUT | EPOLLONESHOT; ev.data.ptr = data; data->sendQueue->push(data); return ::epoll_ctl(epollfd_, EPOLL_CTL_MOD, data->socket->sock, &ev); #endif } } // namespace Chattr