diff --git a/source/eventcore/drivers/winapi/core.d b/source/eventcore/drivers/winapi/core.d index ed89d7e..b78c87f 100644 --- a/source/eventcore/drivers/winapi/core.d +++ b/source/eventcore/drivers/winapi/core.d @@ -36,7 +36,11 @@ final class WinAPIEventDriverCore : EventDriverCore { override size_t waiterCount() { return m_waiterCount + m_timers.pendingCount; } package void addWaiter() { m_waiterCount++; } - package void removeWaiter() { m_waiterCount--; } + package void removeWaiter() + { + assert(m_waiterCount > 0, "Decrementing waiter count below zero."); + m_waiterCount--; + } override ExitReason processEvents(Duration timeout = Duration.max) { @@ -216,6 +220,7 @@ private struct HandleSlot { package struct FileSlot { static struct Direction(bool RO) { OVERLAPPED overlapped; + WinAPIEventDriverCore core; FileIOCallback callback; ulong offset; size_t bytesTransferred; diff --git a/source/eventcore/drivers/winapi/files.d b/source/eventcore/drivers/winapi/files.d index 498db4a..b5900e6 100644 --- a/source/eventcore/drivers/winapi/files.d +++ b/source/eventcore/drivers/winapi/files.d @@ -96,7 +96,9 @@ final class WinAPIEventDriverFiles : EventDriverFiles { slot.offset = offset; slot.buffer = buffer; slot.mode = mode; + slot.core = m_core; slot.callback = on_write_finish; + m_core.addWaiter(); startIO!(WriteFileEx, true)(h, slot); } @@ -113,7 +115,9 @@ final class WinAPIEventDriverFiles : EventDriverFiles { slot.offset = offset; slot.buffer = buffer; slot.mode = mode; + slot.core = m_core; slot.callback = on_read_finish; + m_core.addWaiter(); startIO!(ReadFileEx, false)(h, slot); } @@ -157,13 +161,15 @@ final class WinAPIEventDriverFiles : EventDriverFiles { auto nbytes = min(slot.buffer.length, DWORD.max); if (!() @trusted { return fun(h, &slot.buffer[0], nbytes, &slot.overlapped, &onIOFinished!(fun, RO)); } ()) { + slot.core.removeWaiter(); slot.invokeCallback(IOStatus.error, slot.bytesTransferred); } } - private static void cancelIO(bool RO)(HANDLE h, ref FileSlot.Direction!RO slot) + private void cancelIO(bool RO)(HANDLE h, ref FileSlot.Direction!RO slot) { if (slot.callback) { + m_core.removeWaiter(); //CancelIoEx(h, &slot.overlapped); // FIXME: currently causes linker errors for DMD due to outdated kernel32.lib files slot.callback = null; slot.buffer = null; @@ -185,6 +191,7 @@ final class WinAPIEventDriverFiles : EventDriverFiles { } if (error != 0) { + slot.core.removeWaiter(); slot.invokeCallback(IOStatus.error, slot.bytesTransferred + bytes_transferred); return; } @@ -193,6 +200,7 @@ final class WinAPIEventDriverFiles : EventDriverFiles { slot.offset += bytes_transferred; if (slot.bytesTransferred >= slot.buffer.length || slot.mode != IOMode.all) { + slot.core.removeWaiter(); slot.invokeCallback(IOStatus.ok, slot.bytesTransferred); } else { startIO!(fun, RO)(h, slot);