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.
This commit is contained in:
Sönke Ludwig 2018-03-03 18:31:26 +01:00
parent 79226e2c60
commit 3a52e0f362
4 changed files with 20 additions and 12 deletions

View file

@ -21,7 +21,7 @@ import eventcore.drivers.winapi.watchers;
import core.sys.windows.windows; import core.sys.windows.windows;
static assert(HANDLE.sizeof <= FD.BaseType.sizeof); 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 { final class WinAPIEventDriver : EventDriver {

View file

@ -142,6 +142,6 @@ final class WinAPIEventDriverEvents : EventDriverEvents {
private static HANDLE idToHandle(EventID event) private static HANDLE idToHandle(EventID event)
@trusted { @trusted {
return cast(HANDLE)cast(int)event; return cast(HANDLE)cast(size_t)event;
} }
} }

View file

@ -43,24 +43,28 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
BOOL ret = SetEndOfFile(handle); BOOL ret = SetEndOfFile(handle);
if (!ret) { if (!ret) {
CloseHandle(handle); CloseHandle(handle);
return FileFD.init; return FileFD.invalid;
} }
} }
return adopt(cast(int)handle); return adoptInternal(handle);
} }
override FileFD adopt(int system_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; DWORD f;
if (!() @trusted { return GetHandleInformation(handle, &f); } ()) if (!() @trusted { return GetHandleInformation(handle, &f); } ())
return FileFD.init; return FileFD.invalid;
auto s = m_core.setupSlot!FileSlot(handle); auto s = m_core.setupSlot!FileSlot(handle);
s.read.handle = s.write.handle = handle; s.read.handle = s.write.handle = handle;
return FileFD(system_handle); return FileFD(cast(size_t)handle);
} }
override void close(FileFD file) override void close(FileFD file)
@ -182,7 +186,7 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
auto slot = () @trusted { return cast(FileSlot.Direction!RO*)overlapped.hEvent; } (); auto slot = () @trusted { return cast(FileSlot.Direction!RO*)overlapped.hEvent; } ();
assert(slot !is null); assert(slot !is null);
HANDLE h = slot.handle; HANDLE h = slot.handle;
auto id = FileFD(cast(int)h); auto id = FileFD(cast(size_t)h);
if (!slot.callback) { if (!slot.callback) {
// request was already cancelled // request was already cancelled
@ -208,6 +212,6 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
private static HANDLE idToHandle(FileFD id) private static HANDLE idToHandle(FileFD id)
@trusted { @trusted {
return cast(HANDLE)cast(int)id; return cast(HANDLE)cast(size_t)id;
} }
} }

View file

@ -35,7 +35,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
return WatcherID.invalid; return WatcherID.invalid;
auto id = WatcherID(cast(int)handle); auto id = WatcherID(cast(size_t)handle);
auto slot = m_core.setupSlot!WatcherSlot(handle); auto slot = m_core.setupSlot!WatcherSlot(handle);
slot.directory = path; slot.directory = path;
@ -80,6 +80,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
try theAllocator.dispose(slot.watcher.buffer); try theAllocator.dispose(slot.watcher.buffer);
catch (Exception e) assert(false, "Freeing directory watcher buffer failed."); catch (Exception e) assert(false, "Freeing directory watcher buffer failed.");
} (); } ();
slot.watcher.buffer = null;
core.freeSlot(handle); core.freeSlot(handle);
})) }))
{ {
@ -91,6 +92,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
// completion callback // completion callback
if (slot.refCount == 1) { if (slot.refCount == 1) {
() @trusted { CancelIoEx(handle, &slot.watcher.overlapped); } (); () @trusted { CancelIoEx(handle, &slot.watcher.overlapped); } ();
slot.watcher.callback = null;
core.removeWaiter(); core.removeWaiter();
} }
@ -105,7 +107,7 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
import std.path : dirName, baseName, buildPath; import std.path : dirName, baseName, buildPath;
auto handle = overlapped.hEvent; // *file* handle 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 gslot = () @trusted { return &WinAPIEventDriver.threadInstance.core.m_handles[handle]; } ();
auto slot = () @trusted { return &gslot.watcher(); } (); auto slot = () @trusted { return &gslot.watcher(); } ();
@ -118,6 +120,8 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
return; return;
} }
if (!slot.callback) return;
// NOTE: cbTransferred can be 0 if the buffer overflowed // NOTE: cbTransferred can be 0 if the buffer overflowed
ubyte[] result = slot.buffer[0 .. cbTransferred]; ubyte[] result = slot.buffer[0 .. cbTransferred];
while (result.length) { while (result.length) {
@ -177,5 +181,5 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers {
return true; 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; }
} }