From 3a52e0f36289eb0440afec778131199cd9e0bec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sat, 3 Mar 2018 18:31:26 +0100 Subject: [PATCH] Fix cast from HANDLE to descriptor in the WinAPI driver. Avoids truncation to 32-bit for 64-bit builds. Also improves robustness of the directory watcher shutdown procedure. --- source/eventcore/drivers/winapi/driver.d | 2 +- source/eventcore/drivers/winapi/events.d | 2 +- source/eventcore/drivers/winapi/files.d | 18 +++++++++++------- source/eventcore/drivers/winapi/watchers.d | 10 +++++++--- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/source/eventcore/drivers/winapi/driver.d b/source/eventcore/drivers/winapi/driver.d index 91d0992..06ba834 100644 --- a/source/eventcore/drivers/winapi/driver.d +++ b/source/eventcore/drivers/winapi/driver.d @@ -21,7 +21,7 @@ import eventcore.drivers.winapi.watchers; import core.sys.windows.windows; static assert(HANDLE.sizeof <= FD.BaseType.sizeof); -static assert(FD(cast(int)INVALID_HANDLE_VALUE) == FD.init); +static assert(FD(cast(size_t)INVALID_HANDLE_VALUE) == FD.init); final class WinAPIEventDriver : EventDriver { diff --git a/source/eventcore/drivers/winapi/events.d b/source/eventcore/drivers/winapi/events.d index 23884e6..c39049a 100644 --- a/source/eventcore/drivers/winapi/events.d +++ b/source/eventcore/drivers/winapi/events.d @@ -142,6 +142,6 @@ final class WinAPIEventDriverEvents : EventDriverEvents { private static HANDLE idToHandle(EventID event) @trusted { - return cast(HANDLE)cast(int)event; + return cast(HANDLE)cast(size_t)event; } } diff --git a/source/eventcore/drivers/winapi/files.d b/source/eventcore/drivers/winapi/files.d index 6ba6159..09492d7 100644 --- a/source/eventcore/drivers/winapi/files.d +++ b/source/eventcore/drivers/winapi/files.d @@ -43,24 +43,28 @@ final class WinAPIEventDriverFiles : EventDriverFiles { BOOL ret = SetEndOfFile(handle); if (!ret) { CloseHandle(handle); - return FileFD.init; + return FileFD.invalid; } } - return adopt(cast(int)handle); + return adoptInternal(handle); } override FileFD adopt(int system_handle) { - auto handle = () @trusted { return cast(HANDLE)system_handle; } (); + return adoptInternal(() @trusted { return cast(HANDLE)system_handle; } ()); + } + + private FileFD adoptInternal(HANDLE handle) + { DWORD f; if (!() @trusted { return GetHandleInformation(handle, &f); } ()) - return FileFD.init; + return FileFD.invalid; auto s = m_core.setupSlot!FileSlot(handle); s.read.handle = s.write.handle = handle; - return FileFD(system_handle); + return FileFD(cast(size_t)handle); } override void close(FileFD file) @@ -182,7 +186,7 @@ final class WinAPIEventDriverFiles : EventDriverFiles { auto slot = () @trusted { return cast(FileSlot.Direction!RO*)overlapped.hEvent; } (); assert(slot !is null); HANDLE h = slot.handle; - auto id = FileFD(cast(int)h); + auto id = FileFD(cast(size_t)h); if (!slot.callback) { // request was already cancelled @@ -208,6 +212,6 @@ final class WinAPIEventDriverFiles : EventDriverFiles { private static HANDLE idToHandle(FileFD id) @trusted { - return cast(HANDLE)cast(int)id; + return cast(HANDLE)cast(size_t)id; } } diff --git a/source/eventcore/drivers/winapi/watchers.d b/source/eventcore/drivers/winapi/watchers.d index 6d1d60b..1928bce 100644 --- a/source/eventcore/drivers/winapi/watchers.d +++ b/source/eventcore/drivers/winapi/watchers.d @@ -35,7 +35,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers { if (handle == INVALID_HANDLE_VALUE) return WatcherID.invalid; - auto id = WatcherID(cast(int)handle); + auto id = WatcherID(cast(size_t)handle); auto slot = m_core.setupSlot!WatcherSlot(handle); slot.directory = path; @@ -80,6 +80,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers { try theAllocator.dispose(slot.watcher.buffer); catch (Exception e) assert(false, "Freeing directory watcher buffer failed."); } (); + slot.watcher.buffer = null; core.freeSlot(handle); })) { @@ -91,6 +92,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers { // completion callback if (slot.refCount == 1) { () @trusted { CancelIoEx(handle, &slot.watcher.overlapped); } (); + slot.watcher.callback = null; core.removeWaiter(); } @@ -105,7 +107,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers { import std.path : dirName, baseName, buildPath; auto handle = overlapped.hEvent; // *file* handle - auto id = WatcherID(cast(int)handle); + auto id = WatcherID(cast(size_t)handle); auto gslot = () @trusted { return &WinAPIEventDriver.threadInstance.core.m_handles[handle]; } (); auto slot = () @trusted { return &gslot.watcher(); } (); @@ -118,6 +120,8 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers { return; } + if (!slot.callback) return; + // NOTE: cbTransferred can be 0 if the buffer overflowed ubyte[] result = slot.buffer[0 .. cbTransferred]; while (result.length) { @@ -177,5 +181,5 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers { return true; } - static private HANDLE idToHandle(WatcherID id) @trusted { return cast(HANDLE)cast(int)id; } + static private HANDLE idToHandle(WatcherID id) @trusted { return cast(HANDLE)cast(size_t)id; } }