Fix waiter count tracking for WinAPI directory watchers and avoid empty callbacks.

This commit is contained in:
Sönke Ludwig 2017-11-20 15:58:24 +01:00
parent 314bd2bb48
commit fdeef38ef4

View file

@ -31,7 +31,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
null); null);
} (); } ();
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
return WatcherID.invalid; return WatcherID.invalid;
@ -45,12 +45,13 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
try return theAllocator.makeArray!ubyte(16384); try return theAllocator.makeArray!ubyte(16384);
catch (Exception e) assert(false, "Failed to allocate directory watcher buffer."); catch (Exception e) assert(false, "Failed to allocate directory watcher buffer.");
} (); } ();
if (!triggerRead(handle, *slot)) { if (!triggerRead(handle, *slot)) {
releaseRef(id); releaseRef(id);
return WatcherID.invalid; return WatcherID.invalid;
} }
m_core.addWaiter();
return id; return id;
} }
@ -63,6 +64,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
{ {
auto handle = idToHandle(descriptor); auto handle = idToHandle(descriptor);
return m_core.m_handles[handle].releaseRef(()nothrow{ return m_core.m_handles[handle].releaseRef(()nothrow{
m_core.removeWaiter();
CloseHandle(handle); CloseHandle(handle);
() @trusted { () @trusted {
try theAllocator.dispose(m_core.m_handles[handle].watcher.buffer); try theAllocator.dispose(m_core.m_handles[handle].watcher.buffer);
@ -93,11 +95,15 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
if (handle !in WinAPIEventDriver.threadInstance.core.m_handles) if (handle !in WinAPIEventDriver.threadInstance.core.m_handles)
return; return;
// NOTE: can be 0 if the buffer overflowed
if (!cbTransferred)
return;
auto slot = () @trusted { return &WinAPIEventDriver.threadInstance.core.m_handles[handle].watcher(); } (); auto slot = () @trusted { return &WinAPIEventDriver.threadInstance.core.m_handles[handle].watcher(); } ();
ubyte[] result = slot.buffer[0 .. cbTransferred]; ubyte[] result = slot.buffer[0 .. cbTransferred];
do { do {
assert(result.length >= FILE_NOTIFY_INFORMATION.sizeof); assert(result.length >= FILE_NOTIFY_INFORMATION._FileName.offsetof);
auto fni = () @trusted { return cast(FILE_NOTIFY_INFORMATION*)result.ptr; } (); auto fni = () @trusted { return cast(FILE_NOTIFY_INFORMATION*)result.ptr; } ();
FileChange ch; FileChange ch;
switch (fni.Action) { switch (fni.Action) {