emsApplication/3rdPartner/libhv/event/iocp.c

82 lines
2.2 KiB
C

#include "iowatcher.h"
#ifdef EVENT_IOCP
#include "hplatform.h"
#include "hdef.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;
iocp_ctx_t* iocp_ctx;
HV_ALLOC_SIZEOF(iocp_ctx);
iocp_ctx->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
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