Loading src/event/iocp.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <WinSock2.h> #include <mswsock.h> #include <ws2tcpip.h> #include <mstcpip.h> #pragma comment(lib, "Ws2_32.lib") Loading Loading @@ -274,6 +275,25 @@ namespace netplus { c->slots[0].csock = std::move(csock); // Set accepted socket to non-blocking for IOCP c->slots[0].csock->setNonBlock(); // Enable TCP keep-alive to detect dead connections { BOOL keepAlive = TRUE; ::setsockopt(accepted, SOL_SOCKET, SO_KEEPALIVE, (const char*)&keepAlive, sizeof(keepAlive)); // Keep-alive parameters via SIO_KEEPALIVE_VALS (all Windows versions) struct tcp_keepalive ka{}; ka.onoff = 1; ka.keepalivetime = 60000; // ms before first probe ka.keepaliveinterval = 10000; // ms between probes DWORD bytesReturned = 0; ::WSAIoctl(accepted, SIO_KEEPALIVE_VALS, &ka, sizeof(ka), nullptr, 0, &bytesReturned, nullptr, nullptr); } HANDLE h = CreateIoCompletionPort((HANDLE)accepted, st->iocp, (ULONG_PTR)c->slots[0].csock.get(), Loading Loading @@ -334,6 +354,18 @@ namespace netplus { if (!conPtr) continue; con* owner = conPtr.get(); // Handle failed IOCP completion (ok==false, pov!=null) if (!ok) { if (buf->operation == OP_READ) { owner->slots[0].ReadPending.store(false); } else if (buf->operation == OP_WRITE) { owner->slots[0].WritePending.store(false); owner->slots[0].csock->setPendingWrite(false); } try_cleanup_con(ev, st, owner, cs, tid); continue; } // ===== READ completion ===== if (buf->operation == OP_READ) { std::lock_guard<std::recursive_mutex> lock(owner->event_mutex); Loading Loading
src/event/iocp.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <WinSock2.h> #include <mswsock.h> #include <ws2tcpip.h> #include <mstcpip.h> #pragma comment(lib, "Ws2_32.lib") Loading Loading @@ -274,6 +275,25 @@ namespace netplus { c->slots[0].csock = std::move(csock); // Set accepted socket to non-blocking for IOCP c->slots[0].csock->setNonBlock(); // Enable TCP keep-alive to detect dead connections { BOOL keepAlive = TRUE; ::setsockopt(accepted, SOL_SOCKET, SO_KEEPALIVE, (const char*)&keepAlive, sizeof(keepAlive)); // Keep-alive parameters via SIO_KEEPALIVE_VALS (all Windows versions) struct tcp_keepalive ka{}; ka.onoff = 1; ka.keepalivetime = 60000; // ms before first probe ka.keepaliveinterval = 10000; // ms between probes DWORD bytesReturned = 0; ::WSAIoctl(accepted, SIO_KEEPALIVE_VALS, &ka, sizeof(ka), nullptr, 0, &bytesReturned, nullptr, nullptr); } HANDLE h = CreateIoCompletionPort((HANDLE)accepted, st->iocp, (ULONG_PTR)c->slots[0].csock.get(), Loading Loading @@ -334,6 +354,18 @@ namespace netplus { if (!conPtr) continue; con* owner = conPtr.get(); // Handle failed IOCP completion (ok==false, pov!=null) if (!ok) { if (buf->operation == OP_READ) { owner->slots[0].ReadPending.store(false); } else if (buf->operation == OP_WRITE) { owner->slots[0].WritePending.store(false); owner->slots[0].csock->setPendingWrite(false); } try_cleanup_con(ev, st, owner, cs, tid); continue; } // ===== READ completion ===== if (buf->operation == OP_READ) { std::lock_guard<std::recursive_mutex> lock(owner->event_mutex); Loading