From 523e43f63952eb622a0419ebb32cd06a898e5562 Mon Sep 17 00:00:00 2001 From: ithewei Date: Sat, 26 Sep 2026 00:43:09 +0800 Subject: [PATCH 1/2] refactor(event): remove legacy IOCP backend Co-authored-by: TRAE CLI --- CMakeLists.txt | 2 +- docs/cn/hloop.md | 2 +- event/README.md | 7 +- event/hevent.c | 8 +- event/hevent.h | 9 - event/hloop.c | 6 - event/hloop.h | 2 - event/iocp.c | 87 ---------- event/iowatcher.h | 1 - event/nio.c | 2 - event/overlapio.c | 431 ---------------------------------------------- event/overlapio.h | 33 ---- 12 files changed, 6 insertions(+), 584 deletions(-) delete mode 100644 event/iocp.c delete mode 100644 event/overlapio.c delete mode 100644 event/overlapio.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 899b01629..f9499b4b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux") endif() if(WIN32 OR MINGW) - option(WITH_WEPOLL "compile event/wepoll -> use iocp" ON) + option(WITH_WEPOLL "use wepoll on Windows" ON) option(ENABLE_WINDUMP "Windows MiniDumpWriteDump" OFF) option(BUILD_FOR_MT "build for /MT" OFF) if(BUILD_FOR_MT) diff --git a/docs/cn/hloop.md b/docs/cn/hloop.md index 8b6be87bc..3601551e9 100644 --- a/docs/cn/hloop.md +++ b/docs/cn/hloop.md @@ -1,7 +1,7 @@ 事件循环和IO多路复用机制介绍 事件循环是`libevent、libev、libuv、libhv`这类网络库里最核心的概念,即在事件循环里处理IO读写事件、定时器事件、自定义事件等各种事件;
-IO多路复用即在一个IO线程监听多个fd,如最早期的`select`、后来的`poll`,`linux的epoll`、`windows的iocp`、`bsd的kqueue`、`solaris的port`等,都属于IO多路复用机制。
+IO多路复用即在一个IO线程监听多个fd,如最早期的`select`、后来的`poll`,`linux的epoll`、`windows的wepoll/WSAPoll`、`bsd的kqueue`、`solaris的port`等,都属于IO多路复用机制。
非阻塞NIO搭配IO多路复用机制就是高并发的钥匙。
`libhv`下的`event`模块正是封装了多种平台的IO多路复用机制,提供了统一的事件接口,是`libhv`的核心模块。
diff --git a/event/README.md b/event/README.md index 2bf978048..6a5c0ae4b 100644 --- a/event/README.md +++ b/event/README.md @@ -14,12 +14,11 @@ ├── iowatcher.h IO多路复用统一抽象接口 ├── select.c EVENT_SELECT实现 ├── poll.c EVENT_POLL实现 -├── epoll.c EVENT_EPOLL实现 (for OS_LINUX) +├── epoll.c EVENT_EPOLL实现 (for OS_LINUX/OS_WIN with wepoll) +├── wepoll/ Windows epoll兼容实现 ├── io_uring.c EVENT_IO_URING实现 (for OS_LINUX, with liburing) -├── iocp.c EVENT_IOCP实现 (for OS_WIN) ├── kqueue.c EVENT_KQUEUE实现(for OS_BSD/OS_MAC) ├── evport.c EVENT_PORT实现 (for OS_SOLARIS) -├── nio.c 非阻塞IO -└── overlapio.c 重叠IO +└── nio.c 非阻塞IO ``` diff --git a/event/hevent.c b/event/hevent.c index fdc8c5fee..0f888bbd8 100644 --- a/event/hevent.c +++ b/event/hevent.c @@ -88,9 +88,7 @@ void hio_ready(hio_t* io) { io->ready = 1; io->connected = 0; io->closed = 0; - io->accept = io->connect = io->connectex = 0; - io->recv = io->send = 0; - io->recvfrom = io->sendto = 0; + io->accept = io->connect = 0; io->close = 0; // public: io->id = hio_next_id(); @@ -146,10 +144,6 @@ void hio_ready(hio_t* io) { #if defined(EVENT_POLL) || defined(EVENT_KQUEUE) io->event_index[0] = io->event_index[1] = -1; #endif -#ifdef EVENT_IOCP - io->hovlp = NULL; -#endif - // io_type fill_io_type(io); if (io->io_type & HIO_TYPE_SOCKET) { diff --git a/event/hevent.h b/event/hevent.h index 2ef1ae715..06a88e877 100644 --- a/event/hevent.h +++ b/event/hevent.h @@ -140,11 +140,6 @@ struct hio_s { unsigned closed :1; unsigned accept :1; unsigned connect :1; - unsigned connectex :1; // for ConnectEx/DisconnectEx - unsigned recv :1; - unsigned send :1; - unsigned recvfrom :1; - unsigned sendto :1; unsigned close :1; unsigned alloced_readbuf :1; // for hio_alloc_readbuf unsigned alloced_ssl_ctx :1; // for hio_new_ssl_ctx @@ -213,10 +208,6 @@ struct hio_s { int event_index[2]; // for poll,kqueue #endif -#ifdef EVENT_IOCP - void* hovlp; // for iocp/overlapio -#endif - #if WITH_RUDP rudp_t rudp; #if WITH_KCP diff --git a/event/hloop.c b/event/hloop.c index 4a0acd814..75ca8b588 100644 --- a/event/hloop.c +++ b/event/hloop.c @@ -805,8 +805,6 @@ const char* hio_engine() { return "epoll"; #elif defined(EVENT_KQUEUE) return "kqueue"; -#elif defined(EVENT_IOCP) - return "iocp"; #elif defined(EVENT_PORT) return "evport"; #elif defined(EVENT_IO_URING) @@ -1005,7 +1003,6 @@ void hclose (hloop_t* loop, int fd) { hio_t* hrecv (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb) { //hio_t* io = hio_get(loop, connfd); //assert(io != NULL); - //io->recv = 1; //if (io->io_type != HIO_TYPE_SSL) { //io->io_type = HIO_TYPE_TCP; //} @@ -1015,7 +1012,6 @@ hio_t* hrecv (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb hio_t* hsend (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb write_cb) { //hio_t* io = hio_get(loop, connfd); //assert(io != NULL); - //io->send = 1; //if (io->io_type != HIO_TYPE_SSL) { //io->io_type = HIO_TYPE_TCP; //} @@ -1025,7 +1021,6 @@ hio_t* hsend (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb read_cb) { //hio_t* io = hio_get(loop, sockfd); //assert(io != NULL); - //io->recvfrom = 1; //io->io_type = HIO_TYPE_UDP; return hread(loop, sockfd, buf, len, read_cb); } @@ -1033,7 +1028,6 @@ hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb rea hio_t* hsendto (hloop_t* loop, int sockfd, const void* buf, size_t len, hwrite_cb write_cb) { //hio_t* io = hio_get(loop, sockfd); //assert(io != NULL); - //io->sendto = 1; //io->io_type = HIO_TYPE_UDP; return hwrite(loop, sockfd, buf, len, write_cb); } diff --git a/event/hloop.h b/event/hloop.h index 8855b93c1..b074d8ab5 100644 --- a/event/hloop.h +++ b/event/hloop.h @@ -252,8 +252,6 @@ const char* hio_engine() { return "epoll"; #elif defined(EVENT_KQUEUE) return "kqueue"; -#elif defined(EVENT_IOCP) - return "iocp"; #elif defined(EVENT_PORT) return "evport"; #elif defined(EVENT_IO_URING) diff --git a/event/iocp.c b/event/iocp.c deleted file mode 100644 index 5463bb96d..000000000 --- a/event/iocp.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "iowatcher.h" - -#ifdef EVENT_IOCP -#include "hplatform.h" -#include "hdef.h" -#include "hlog.h" - -#include "hevent.h" -#include "overlapio.h" - -typedef struct iocp_ctx_s { - HANDLE iocp; -} iocp_ctx_t; - -int iowatcher_init(hloop_t* loop) { - if (loop->iowatcher) return 0; - HANDLE iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); - if (iocp == NULL) { - hloge("CreateIoCompletionPort failed: %d", GetLastError()); - return -1; - } - iocp_ctx_t* iocp_ctx; - HV_ALLOC_SIZEOF(iocp_ctx); - iocp_ctx->iocp = iocp; - loop->iowatcher = iocp_ctx; - return 0; -} - -int iowatcher_cleanup(hloop_t* loop) { - if (loop->iowatcher == NULL) return 0; - iocp_ctx_t* iocp_ctx = (iocp_ctx_t*)loop->iowatcher; - CloseHandle(iocp_ctx->iocp); - HV_FREE(loop->iowatcher); - return 0; -} - -int iowatcher_add_event(hloop_t* loop, int fd, int events) { - if (loop->iowatcher == NULL) { - iowatcher_init(loop); - } - iocp_ctx_t* iocp_ctx = (iocp_ctx_t*)loop->iowatcher; - hio_t* io = loop->ios.ptr[fd]; - if (io && io->events == 0 && events != 0) { - CreateIoCompletionPort((HANDLE)fd, iocp_ctx->iocp, 0, 0); - } - return 0; -} - -int iowatcher_del_event(hloop_t* loop, int fd, int events) { - hio_t* io = loop->ios.ptr[fd]; - if ((io->events & ~events) == 0) { - CancelIo((HANDLE)fd); - } - return 0; -} - -int iowatcher_poll_events(hloop_t* loop, int timeout) { - if (loop->iowatcher == NULL) return 0; - iocp_ctx_t* iocp_ctx = (iocp_ctx_t*)loop->iowatcher; - DWORD bytes = 0; - ULONG_PTR key = 0; - LPOVERLAPPED povlp = NULL; - BOOL bRet = GetQueuedCompletionStatus(iocp_ctx->iocp, &bytes, &key, &povlp, timeout); - int err = 0; - if (povlp == NULL) { - err = WSAGetLastError(); - if (err == WAIT_TIMEOUT || ERROR_NETNAME_DELETED || ERROR_OPERATION_ABORTED) { - return 0; - } - return -err; - } - hoverlapped_t* hovlp = (hoverlapped_t*)povlp; - hio_t* io = hovlp->io; - if (bRet == FALSE) { - err = WSAGetLastError(); - printd("iocp ret=%d err=%d bytes=%u\n", bRet, err, bytes); - // NOTE: when ConnectEx failed, err != 0 - hovlp->error = err; - } - // NOTE: when WSASend/WSARecv disconnect, bytes = 0 - hovlp->bytes = bytes; - io->hovlp = hovlp; - io->revents |= hovlp->event; - EVENT_PENDING(hovlp->io); - return 1; -} -#endif diff --git a/event/iowatcher.h b/event/iowatcher.h index 5432bc9df..1004d301b 100644 --- a/event/iowatcher.h +++ b/event/iowatcher.h @@ -8,7 +8,6 @@ !defined(EVENT_POLL) && \ !defined(EVENT_EPOLL) && \ !defined(EVENT_KQUEUE) && \ - !defined(EVENT_IOCP) && \ !defined(EVENT_PORT) && \ !defined(EVENT_IO_URING) && \ !defined(EVENT_NOEVENT) diff --git a/event/nio.c b/event/nio.c index 2438d520f..274834f74 100644 --- a/event/nio.c +++ b/event/nio.c @@ -1,5 +1,4 @@ #include "iowatcher.h" -#ifndef EVENT_IOCP #include "hevent.h" #include "hsocket.h" #include "hssl.h" @@ -635,4 +634,3 @@ int hio_close (hio_t* io) { } return 0; } -#endif diff --git a/event/overlapio.c b/event/overlapio.c deleted file mode 100644 index 61f24937f..000000000 --- a/event/overlapio.c +++ /dev/null @@ -1,431 +0,0 @@ -// WARN: overlapio maybe need MemoryPool to avoid alloc/free -#include "iowatcher.h" - -#ifdef EVENT_IOCP -#include "overlapio.h" -#include "hevent.h" - -#define ACCEPTEX_NUM 10 - -int post_acceptex(hio_t* listenio, hoverlapped_t* hovlp) { - LPFN_ACCEPTEX AcceptEx = NULL; - GUID guidAcceptEx = WSAID_ACCEPTEX; - DWORD dwbytes = 0; - if (WSAIoctl(listenio->fd, SIO_GET_EXTENSION_FUNCTION_POINTER, - &guidAcceptEx, sizeof(guidAcceptEx), - &AcceptEx, sizeof(AcceptEx), - &dwbytes, NULL, NULL) != 0) { - return WSAGetLastError(); - } - int connfd = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); - if (connfd < 0) { - return WSAGetLastError(); - } - if (hovlp == NULL) { - HV_ALLOC_SIZEOF(hovlp); - hovlp->buf.len = 20 + sizeof(struct sockaddr_in6) * 2; - HV_ALLOC(hovlp->buf.buf, hovlp->buf.len); - } - hovlp->fd = connfd; - hovlp->event = HV_READ; - hovlp->io = listenio; - if (AcceptEx(listenio->fd, connfd, hovlp->buf.buf, 0, sizeof(struct sockaddr_in6), sizeof(struct sockaddr_in6), - &dwbytes, &hovlp->ovlp) != TRUE) { - int err = WSAGetLastError(); - if (err != ERROR_IO_PENDING) { - fprintf(stderr, "AcceptEx error: %d\n", err); - return err; - } - } - return 0; -} - -int post_recv(hio_t* io, hoverlapped_t* hovlp) { - if (hovlp == NULL) { - HV_ALLOC_SIZEOF(hovlp); - } - hovlp->fd = io->fd; - hovlp->event = HV_READ; - hovlp->io = io; - hovlp->buf.len = io->readbuf.len; - if (io->io_type == HIO_TYPE_UDP || io->io_type == HIO_TYPE_IP) { - HV_ALLOC(hovlp->buf.buf, hovlp->buf.len); - } - else { - hovlp->buf.buf = io->readbuf.base; - } - //memset(hovlp->buf.buf, 0, hovlp->buf.len); - DWORD dwbytes = 0; - DWORD flags = 0; - int ret = 0; - if (io->io_type == HIO_TYPE_TCP) { - ret = WSARecv(io->fd, &hovlp->buf, 1, &dwbytes, &flags, &hovlp->ovlp, NULL); - } - else if (io->io_type == HIO_TYPE_UDP || - io->io_type == HIO_TYPE_IP) { - if (hovlp->addr == NULL) { - hovlp->addrlen = sizeof(struct sockaddr_in6); - HV_ALLOC(hovlp->addr, sizeof(struct sockaddr_in6)); - } - ret = WSARecvFrom(io->fd, &hovlp->buf, 1, &dwbytes, &flags, hovlp->addr, &hovlp->addrlen, &hovlp->ovlp, NULL); - } - else { - ret = -1; - } - //printd("WSARecv ret=%d bytes=%u\n", ret, dwbytes); - if (ret != 0) { - int err = WSAGetLastError(); - if (err != ERROR_IO_PENDING) { - fprintf(stderr, "WSARecv error: %d\n", err); - return err; - } - } - return 0; -} - -static void on_acceptex_complete(hio_t* io) { - printd("on_acceptex_complete------\n"); - hoverlapped_t* hovlp = (hoverlapped_t*)io->hovlp; - int listenfd = io->fd; - int connfd = hovlp->fd; - LPFN_GETACCEPTEXSOCKADDRS GetAcceptExSockaddrs = NULL; - GUID guidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS; - DWORD dwbytes = 0; - if (WSAIoctl(connfd, SIO_GET_EXTENSION_FUNCTION_POINTER, - &guidGetAcceptExSockaddrs, sizeof(guidGetAcceptExSockaddrs), - &GetAcceptExSockaddrs, sizeof(GetAcceptExSockaddrs), - &dwbytes, NULL, NULL) != 0) { - return; - } - struct sockaddr* plocaladdr = NULL; - struct sockaddr* ppeeraddr = NULL; - socklen_t localaddrlen; - socklen_t peeraddrlen; - GetAcceptExSockaddrs(hovlp->buf.buf, 0, sizeof(struct sockaddr_in6), sizeof(struct sockaddr_in6), - &plocaladdr, &localaddrlen, &ppeeraddr, &peeraddrlen); - memcpy(io->localaddr, plocaladdr, localaddrlen); - memcpy(io->peeraddr, ppeeraddr, peeraddrlen); - if (io->accept_cb) { - setsockopt(connfd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (const char*)&listenfd, sizeof(int)); - hio_t* connio = hio_get(io->loop, connfd); - connio->userdata = io->userdata; - memcpy(connio->localaddr, io->localaddr, localaddrlen); - memcpy(connio->peeraddr, io->peeraddr, peeraddrlen); - /* - char localaddrstr[SOCKADDR_STRLEN] = {0}; - char peeraddrstr[SOCKADDR_STRLEN] = {0}; - printd("accept listenfd=%d connfd=%d [%s] <= [%s]\n", listenfd, connfd, - SOCKADDR_STR(connio->localaddr, localaddrstr), - SOCKADDR_STR(connio->peeraddr, peeraddrstr)); - */ - //printd("accept_cb------\n"); - io->accept_cb(connio); - //printd("accept_cb======\n"); - } - post_acceptex(io, hovlp); -} - -static void on_connectex_complete(hio_t* io) { - printd("on_connectex_complete------\n"); - hoverlapped_t* hovlp = (hoverlapped_t*)io->hovlp; - io->error = hovlp->error; - HV_FREE(io->hovlp); - if (io->error != 0) { - hio_close(io); - return; - } - if (io->connect_cb) { - setsockopt(io->fd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0); - socklen_t addrlen = sizeof(struct sockaddr_in6); - getsockname(io->fd, io->localaddr, &addrlen); - addrlen = sizeof(struct sockaddr_in6); - getpeername(io->fd, io->peeraddr, &addrlen); - /* - char localaddrstr[SOCKADDR_STRLEN] = {0}; - char peeraddrstr[SOCKADDR_STRLEN] = {0}; - printd("connect connfd=%d [%s] => [%s]\n", io->fd, - SOCKADDR_STR(io->localaddr, localaddrstr), - SOCKADDR_STR(io->peeraddr, peeraddrstr)); - */ - //printd("connect_cb------\n"); - io->connect_cb(io); - //printd("connect_cb======\n"); - } -} - -static void on_wsarecv_complete(hio_t* io) { - printd("on_recv_complete------\n"); - hoverlapped_t* hovlp = (hoverlapped_t*)io->hovlp; - if (hovlp->bytes == 0) { - io->error = WSAGetLastError(); - hio_close(io); - return; - } - - if (io->read_cb) { - if (io->io_type == HIO_TYPE_UDP || io->io_type == HIO_TYPE_IP) { - if (hovlp->addr && hovlp->addrlen) { - hio_set_peeraddr(io, hovlp->addr, hovlp->addrlen); - } - } - //printd("read_cb------\n"); - io->read_cb(io, hovlp->buf.buf, hovlp->bytes); - //printd("read_cb======\n"); - } - - if (io->io_type == HIO_TYPE_TCP) { - // reuse hovlp - if (!io->closed) { - post_recv(io, hovlp); - } - } - else if (io->io_type == HIO_TYPE_UDP || - io->io_type == HIO_TYPE_IP) { - HV_FREE(hovlp->buf.buf); - HV_FREE(hovlp->addr); - HV_FREE(io->hovlp); - } -} - -static void on_wsasend_complete(hio_t* io) { - printd("on_send_complete------\n"); - hoverlapped_t* hovlp = (hoverlapped_t*)io->hovlp; - if (hovlp->bytes == 0) { - io->error = WSAGetLastError(); - hio_close(io); - goto end; - } - if (io->write_cb) { - if (io->io_type == HIO_TYPE_UDP || io->io_type == HIO_TYPE_IP) { - if (hovlp->addr) { - hio_set_peeraddr(io, hovlp->addr, hovlp->addrlen); - } - } - //printd("write_cb------\n"); - io->write_cb(io, hovlp->buf.buf, hovlp->bytes); - //printd("write_cb======\n"); - } -end: - if (io->hovlp) { - HV_FREE(hovlp->buf.buf); - HV_FREE(io->hovlp); - } -} - -static void hio_handle_events(hio_t* io) { - if ((io->events & HV_READ) && (io->revents & HV_READ)) { - if (io->accept) { - on_acceptex_complete(io); - } - else { - on_wsarecv_complete(io); - } - } - - if ((io->events & HV_WRITE) && (io->revents & HV_WRITE)) { - // NOTE: HV_WRITE just do once - // ONESHOT - iowatcher_del_event(io->loop, io->fd, HV_WRITE); - io->events &= ~HV_WRITE; - if (io->connect) { - io->connect = 0; - - on_connectex_complete(io); - } - else { - on_wsasend_complete(io); - } - } - - io->revents = 0; -} - -int hio_accept (hio_t* io) { - for (int i = 0; i < ACCEPTEX_NUM; ++i) { - post_acceptex(io, NULL); - } - io->accept = 1; - return hio_add(io, hio_handle_events, HV_READ); -} - -int hio_connect (hio_t* io) { - // NOTE: ConnectEx must call bind - struct sockaddr_in localaddr; - socklen_t addrlen = sizeof(localaddr); - memset(&localaddr, 0, addrlen); - localaddr.sin_family = AF_INET; - localaddr.sin_addr.s_addr = htonl(INADDR_ANY); - localaddr.sin_port = htons(0); - if (bind(io->fd, (struct sockaddr*)&localaddr, addrlen) < 0) { - perror("bind"); - goto error; - } - // ConnectEx - io->connectex = 1; - LPFN_CONNECTEX ConnectEx = NULL; - GUID guidConnectEx = WSAID_CONNECTEX; - DWORD dwbytes; - if (WSAIoctl(io->fd, SIO_GET_EXTENSION_FUNCTION_POINTER, - &guidConnectEx, sizeof(guidConnectEx), - &ConnectEx, sizeof(ConnectEx), - &dwbytes, NULL, NULL) != 0) { - goto error; - } - // NOTE: free on_connectex_complete - hoverlapped_t* hovlp; - HV_ALLOC_SIZEOF(hovlp); - hovlp->fd = io->fd; - hovlp->event = HV_WRITE; - hovlp->io = io; - if (ConnectEx(io->fd, io->peeraddr, sizeof(struct sockaddr_in6), NULL, 0, &dwbytes, &hovlp->ovlp) != TRUE) { - int err = WSAGetLastError(); - if (err != ERROR_IO_PENDING) { - fprintf(stderr, "AcceptEx error: %d\n", err); - goto error; - } - } - io->connect = 1; - return hio_add(io, hio_handle_events, HV_WRITE); -error: - hio_close(io); - return 0; -} - -int hio_read (hio_t* io) { - post_recv(io, NULL); - return hio_add(io, hio_handle_events, HV_READ); -} - -static int hio_write4 (hio_t* io, const void* buf, size_t len, struct sockaddr* addr) { - int nwrite = 0; -try_send: - if (io->io_type == HIO_TYPE_TCP) { - nwrite = send(io->fd, buf, len, 0); - } - else if (io->io_type == HIO_TYPE_UDP) { - if (addr == NULL) addr = io->peeraddr; - nwrite = sendto(io->fd, buf, len, 0, addr, sizeof(struct sockaddr_in6)); - } - else if (io->io_type == HIO_TYPE_IP) { - goto WSASend; - } - else { - nwrite = -1; - } - //printd("write retval=%d\n", nwrite); - if (nwrite < 0) { - if (socket_errno() == EAGAIN) { - nwrite = 0; - goto WSASend; - } - else { - perror("write"); - io->error = socket_errno(); - goto write_error; - } - } - if (nwrite == 0) { - goto disconnect; - } - if (io->write_cb) { - //printd("try_write_cb------\n"); - io->write_cb(io, buf, nwrite); - //printd("try_write_cb======\n"); - } - if (nwrite == len) { - //goto write_done; - return nwrite; - } -WSASend: - { - hoverlapped_t* hovlp; - HV_ALLOC_SIZEOF(hovlp); - hovlp->fd = io->fd; - hovlp->event = HV_WRITE; - hovlp->buf.len = len - nwrite; - // NOTE: free on_send_complete - HV_ALLOC(hovlp->buf.buf, hovlp->buf.len); - memcpy(hovlp->buf.buf, ((char*)buf) + nwrite, hovlp->buf.len); - hovlp->io = io; - DWORD dwbytes = 0; - DWORD flags = 0; - int ret = 0; - if (io->io_type == HIO_TYPE_TCP) { - ret = WSASend(io->fd, &hovlp->buf, 1, &dwbytes, flags, &hovlp->ovlp, NULL); - } - else if (io->io_type == HIO_TYPE_UDP || - io->io_type == HIO_TYPE_IP) { - if (addr == NULL) addr = io->peeraddr; - ret = WSASendTo(io->fd, &hovlp->buf, 1, &dwbytes, flags, addr, sizeof(struct sockaddr_in6), &hovlp->ovlp, NULL); - } - else { - ret = -1; - } - //printd("WSASend ret=%d bytes=%u\n", ret, dwbytes); - if (ret != 0) { - int err = WSAGetLastError(); - if (err != ERROR_IO_PENDING) { - fprintf(stderr, "WSASend error: %d\n", err); - return ret; - } - } - return hio_add(io, hio_handle_events, HV_WRITE); - } -write_error: -disconnect: - if (io->io_type & HIO_TYPE_SOCK_STREAM) { - hio_close(io); - } - return 0; -} - -int hio_write (hio_t* io, const void* buf, size_t len) { - return hio_write4(io, buf, len, io->peeraddr); -} - -int hio_sendto (hio_t* io, const void* buf, size_t len, struct sockaddr* addr) { - return hio_write4(io, buf, len, addr ? addr : io->peeraddr); -} - -int hio_close (hio_t* io) { - if (io->closed) return 0; - io->closed = 1; - hio_done(io); - if (io->hovlp) { - hoverlapped_t* hovlp = (hoverlapped_t*)io->hovlp; - // NOTE: hread buf provided by caller - if (hovlp->buf.buf != io->readbuf.base) { - HV_FREE(hovlp->buf.buf); - } - HV_FREE(hovlp->addr); - HV_FREE(io->hovlp); - } - if (io->close_cb) { - //printd("close_cb------\n"); - io->close_cb(io); - //printd("close_cb======\n"); - } - if (io->io_type & HIO_TYPE_SOCKET) { -#ifdef USE_DISCONNECTEX - // DisconnectEx reuse socket - if (io->connectex) { - io->connectex = 0; - LPFN_DISCONNECTEX DisconnectEx = NULL; - GUID guidDisconnectEx = WSAID_DISCONNECTEX; - DWORD dwbytes; - if (WSAIoctl(io->fd, SIO_GET_EXTENSION_FUNCTION_POINTER, - &guidDisconnectEx, sizeof(guidDisconnectEx), - &DisconnectEx, sizeof(DisconnectEx), - &dwbytes, NULL, NULL) != 0) { - return; - } - DisconnectEx(io->fd, NULL, 0, 0); - } -#else - closesocket(io->fd); -#endif - } - return 0; -} - -#endif diff --git a/event/overlapio.h b/event/overlapio.h deleted file mode 100644 index 69fb0267d..000000000 --- a/event/overlapio.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HV_OVERLAPPED_H_ -#define HV_OVERLAPPED_H_ - -#include "iowatcher.h" - -#ifdef EVENT_IOCP - -#include "hbuf.h" -#include "hsocket.h" -#include -#ifdef _MSC_VER -#pragma comment(lib, "mswsock.lib") -#endif - -typedef struct hoverlapped_s { - OVERLAPPED ovlp; - int fd; - int event; - WSABUF buf; - int bytes; - int error; - hio_t* io; - // for recvfrom - struct sockaddr* addr; - int addrlen; -} hoverlapped_t; - -int post_acceptex(hio_t* listenio, hoverlapped_t* hovlp); -int post_recv(hio_t* io, hoverlapped_t* hovlp); - -#endif - -#endif // HV_OVERLAPPED_H_ From 9750e5a8898bed5dce0f9150f106bc0ed1557baf Mon Sep 17 00:00:00 2001 From: ithewei Date: Sat, 26 Sep 2026 00:52:10 +0800 Subject: [PATCH 2/2] refactor(event): narrow IOCP cleanup Co-authored-by: TRAE CLI --- CMakeLists.txt | 2 +- event/hevent.c | 2 ++ event/hevent.h | 4 ++++ event/hloop.c | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f9499b4b7..899b01629 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux") endif() if(WIN32 OR MINGW) - option(WITH_WEPOLL "use wepoll on Windows" ON) + option(WITH_WEPOLL "compile event/wepoll -> use iocp" ON) option(ENABLE_WINDUMP "Windows MiniDumpWriteDump" OFF) option(BUILD_FOR_MT "build for /MT" OFF) if(BUILD_FOR_MT) diff --git a/event/hevent.c b/event/hevent.c index 0f888bbd8..49cb525c0 100644 --- a/event/hevent.c +++ b/event/hevent.c @@ -89,6 +89,8 @@ void hio_ready(hio_t* io) { io->connected = 0; io->closed = 0; io->accept = io->connect = 0; + io->recv = io->send = 0; + io->recvfrom = io->sendto = 0; io->close = 0; // public: io->id = hio_next_id(); diff --git a/event/hevent.h b/event/hevent.h index 06a88e877..92c69070e 100644 --- a/event/hevent.h +++ b/event/hevent.h @@ -140,6 +140,10 @@ struct hio_s { unsigned closed :1; unsigned accept :1; unsigned connect :1; + unsigned recv :1; + unsigned send :1; + unsigned recvfrom :1; + unsigned sendto :1; unsigned close :1; unsigned alloced_readbuf :1; // for hio_alloc_readbuf unsigned alloced_ssl_ctx :1; // for hio_new_ssl_ctx diff --git a/event/hloop.c b/event/hloop.c index 75ca8b588..464f5d9da 100644 --- a/event/hloop.c +++ b/event/hloop.c @@ -1003,6 +1003,7 @@ void hclose (hloop_t* loop, int fd) { hio_t* hrecv (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb) { //hio_t* io = hio_get(loop, connfd); //assert(io != NULL); + //io->recv = 1; //if (io->io_type != HIO_TYPE_SSL) { //io->io_type = HIO_TYPE_TCP; //} @@ -1012,6 +1013,7 @@ hio_t* hrecv (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb hio_t* hsend (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb write_cb) { //hio_t* io = hio_get(loop, connfd); //assert(io != NULL); + //io->send = 1; //if (io->io_type != HIO_TYPE_SSL) { //io->io_type = HIO_TYPE_TCP; //} @@ -1021,6 +1023,7 @@ hio_t* hsend (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb read_cb) { //hio_t* io = hio_get(loop, sockfd); //assert(io != NULL); + //io->recvfrom = 1; //io->io_type = HIO_TYPE_UDP; return hread(loop, sockfd, buf, len, read_cb); } @@ -1028,6 +1031,7 @@ hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb rea hio_t* hsendto (hloop_t* loop, int sockfd, const void* buf, size_t len, hwrite_cb write_cb) { //hio_t* io = hio_get(loop, sockfd); //assert(io != NULL); + //io->sendto = 1; //io->io_type = HIO_TYPE_UDP; return hwrite(loop, sockfd, buf, len, write_cb); }