Properly increment waiter count for WinAPI file I/O operations.
This commit is contained in:
parent
2e3f145f0f
commit
2d4ccf454d
|
@ -36,7 +36,11 @@ final class WinAPIEventDriverCore : EventDriverCore {
|
||||||
override size_t waiterCount() { return m_waiterCount + m_timers.pendingCount; }
|
override size_t waiterCount() { return m_waiterCount + m_timers.pendingCount; }
|
||||||
|
|
||||||
package void addWaiter() { m_waiterCount++; }
|
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)
|
override ExitReason processEvents(Duration timeout = Duration.max)
|
||||||
{
|
{
|
||||||
|
@ -216,6 +220,7 @@ private struct HandleSlot {
|
||||||
package struct FileSlot {
|
package struct FileSlot {
|
||||||
static struct Direction(bool RO) {
|
static struct Direction(bool RO) {
|
||||||
OVERLAPPED overlapped;
|
OVERLAPPED overlapped;
|
||||||
|
WinAPIEventDriverCore core;
|
||||||
FileIOCallback callback;
|
FileIOCallback callback;
|
||||||
ulong offset;
|
ulong offset;
|
||||||
size_t bytesTransferred;
|
size_t bytesTransferred;
|
||||||
|
|
|
@ -96,7 +96,9 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
|
||||||
slot.offset = offset;
|
slot.offset = offset;
|
||||||
slot.buffer = buffer;
|
slot.buffer = buffer;
|
||||||
slot.mode = mode;
|
slot.mode = mode;
|
||||||
|
slot.core = m_core;
|
||||||
slot.callback = on_write_finish;
|
slot.callback = on_write_finish;
|
||||||
|
m_core.addWaiter();
|
||||||
startIO!(WriteFileEx, true)(h, slot);
|
startIO!(WriteFileEx, true)(h, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +115,9 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
|
||||||
slot.offset = offset;
|
slot.offset = offset;
|
||||||
slot.buffer = buffer;
|
slot.buffer = buffer;
|
||||||
slot.mode = mode;
|
slot.mode = mode;
|
||||||
|
slot.core = m_core;
|
||||||
slot.callback = on_read_finish;
|
slot.callback = on_read_finish;
|
||||||
|
m_core.addWaiter();
|
||||||
startIO!(ReadFileEx, false)(h, slot);
|
startIO!(ReadFileEx, false)(h, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,13 +161,15 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
|
||||||
|
|
||||||
auto nbytes = min(slot.buffer.length, DWORD.max);
|
auto nbytes = min(slot.buffer.length, DWORD.max);
|
||||||
if (!() @trusted { return fun(h, &slot.buffer[0], nbytes, &slot.overlapped, &onIOFinished!(fun, RO)); } ()) {
|
if (!() @trusted { return fun(h, &slot.buffer[0], nbytes, &slot.overlapped, &onIOFinished!(fun, RO)); } ()) {
|
||||||
|
slot.core.removeWaiter();
|
||||||
slot.invokeCallback(IOStatus.error, slot.bytesTransferred);
|
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) {
|
if (slot.callback) {
|
||||||
|
m_core.removeWaiter();
|
||||||
//CancelIoEx(h, &slot.overlapped); // FIXME: currently causes linker errors for DMD due to outdated kernel32.lib files
|
//CancelIoEx(h, &slot.overlapped); // FIXME: currently causes linker errors for DMD due to outdated kernel32.lib files
|
||||||
slot.callback = null;
|
slot.callback = null;
|
||||||
slot.buffer = null;
|
slot.buffer = null;
|
||||||
|
@ -185,6 +191,7 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
|
slot.core.removeWaiter();
|
||||||
slot.invokeCallback(IOStatus.error, slot.bytesTransferred + bytes_transferred);
|
slot.invokeCallback(IOStatus.error, slot.bytesTransferred + bytes_transferred);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -193,6 +200,7 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
|
||||||
slot.offset += bytes_transferred;
|
slot.offset += bytes_transferred;
|
||||||
|
|
||||||
if (slot.bytesTransferred >= slot.buffer.length || slot.mode != IOMode.all) {
|
if (slot.bytesTransferred >= slot.buffer.length || slot.mode != IOMode.all) {
|
||||||
|
slot.core.removeWaiter();
|
||||||
slot.invokeCallback(IOStatus.ok, slot.bytesTransferred);
|
slot.invokeCallback(IOStatus.ok, slot.bytesTransferred);
|
||||||
} else {
|
} else {
|
||||||
startIO!(fun, RO)(h, slot);
|
startIO!(fun, RO)(h, slot);
|
||||||
|
|
Loading…
Reference in a new issue