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;
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 {

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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; }
}