From f094b3934bef7fb4306b805a7be44c67ea0cbd05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sun, 11 Mar 2018 20:15:58 +0100 Subject: [PATCH] Make sure that no obsolete I/O events get processed. Removes overlapped I/O events when a handle gets closed prematurely (before all events have been processed) to avoid potential range violation errors as a consequence. --- source/eventcore/drivers/winapi/core.d | 6 ++++++ source/eventcore/drivers/winapi/files.d | 4 +++- source/eventcore/drivers/winapi/sockets.d | 9 ++++++--- source/eventcore/drivers/winapi/watchers.d | 1 + 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/source/eventcore/drivers/winapi/core.d b/source/eventcore/drivers/winapi/core.d index 6dac979..d426fce 100644 --- a/source/eventcore/drivers/winapi/core.d +++ b/source/eventcore/drivers/winapi/core.d @@ -184,6 +184,12 @@ final class WinAPIEventDriverCore : EventDriverCore { nogc_assert((h in m_handles) !is null, "Handle not in use - cannot free."); m_handles.remove(h); } + + package void discardEvents(scope OVERLAPPED_CORE*[] overlapped...) + { + import std.algorithm.searching : canFind; + m_ioEvents.filterPending!(evt => !overlapped.canFind(evt.overlapped)); + } } private long currStdTime() diff --git a/source/eventcore/drivers/winapi/files.d b/source/eventcore/drivers/winapi/files.d index af63e27..3297989 100644 --- a/source/eventcore/drivers/winapi/files.d +++ b/source/eventcore/drivers/winapi/files.d @@ -146,8 +146,10 @@ final class WinAPIEventDriverFiles : EventDriverFiles { override bool releaseRef(FileFD descriptor) { auto h = idToHandle(descriptor); - return m_core.m_handles[h].releaseRef({ + auto slot = &m_core.m_handles[h]; + return slot.releaseRef({ close(descriptor); + m_core.discardEvents(&slot.file.read.overlapped, &slot.file.write.overlapped); m_core.freeSlot(h); }); } diff --git a/source/eventcore/drivers/winapi/sockets.d b/source/eventcore/drivers/winapi/sockets.d index 8e5eba3..4d9b9b4 100644 --- a/source/eventcore/drivers/winapi/sockets.d +++ b/source/eventcore/drivers/winapi/sockets.d @@ -697,13 +697,15 @@ final class WinAPIEventDriverSockets : EventDriverSockets { override bool releaseRef(SocketFD fd) { import taggedalgebraic : hasType; - nogc_assert(m_sockets[fd].common.refCount > 0, "Releasing reference to unreferenced socket FD."); - if (--m_sockets[fd].common.refCount == 0) { - final switch (m_sockets[fd].specific.kind) with (SocketVector.FieldType) { + auto slot = () @trusted { return &m_sockets[fd]; } (); + nogc_assert(slot.common.refCount > 0, "Releasing reference to unreferenced socket FD."); + if (--slot.common.refCount == 0) { + final switch (slot.specific.kind) with (SocketVector.FieldType) { case Kind.none: break; case Kind.streamSocket: cancelRead(cast(StreamSocketFD)fd); cancelWrite(cast(StreamSocketFD)fd); + m_core.discardEvents(&slot.streamSocket.read.overlapped, &slot.streamSocket.write.overlapped); break; case Kind.streamListen: if (m_sockets[fd].streamListen.acceptCallback) @@ -712,6 +714,7 @@ final class WinAPIEventDriverSockets : EventDriverSockets { case Kind.datagramSocket: cancelReceive(cast(DatagramSocketFD)fd); cancelSend(cast(DatagramSocketFD)fd); + m_core.discardEvents(&slot.datagramSocket.read.overlapped, &slot.datagramSocket.write.overlapped); break; } diff --git a/source/eventcore/drivers/winapi/watchers.d b/source/eventcore/drivers/winapi/watchers.d index 524af9d..9606148 100644 --- a/source/eventcore/drivers/winapi/watchers.d +++ b/source/eventcore/drivers/winapi/watchers.d @@ -82,6 +82,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers { catch (Exception e) assert(false, "Freeing directory watcher buffer failed."); } (); slot.watcher.buffer = null; + core.discardEvents(&slot.watcher.overlapped, &slot.file.write.overlapped); core.freeSlot(handle); })) {