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.
This commit is contained in:
parent
26907c7489
commit
f094b3934b
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue