From 64f6bb2a140cf816fc28795622a6dbfa60cb7dcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sat, 21 Jan 2017 16:19:34 +0100 Subject: [PATCH] Make the select based configuration compile on Windows. --- README.md | 2 +- source/eventcore/drivers/posix.d | 77 +++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 90a0625..9372f53 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Supported drivers and operating systems Driver | Linux | Windows | OS X | FreeBSD ------------------|-------|---------|------|-------- -SelectEventDriver | yes | yes¹ | yes¹ | yes¹ +SelectEventDriver | yes | yes | yes¹ | yes¹ EpollEventDriver | yes | no | no | no WinAPIEventDriver | no | yes¹ | no | no KqueueEventDriver | no | no | yes¹ | yes¹ diff --git a/source/eventcore/drivers/posix.d b/source/eventcore/drivers/posix.d index ad5f7eb..361f8d8 100644 --- a/source/eventcore/drivers/posix.d +++ b/source/eventcore/drivers/posix.d @@ -24,6 +24,7 @@ version (Posix) { import core.sys.posix.fcntl; } version (Windows) { + import core.sys.windows.windows; import core.sys.windows.winsock2; alias sockaddr_storage = SOCKADDR_STORAGE; alias EAGAIN = WSAEWOULDBLOCK; @@ -58,8 +59,9 @@ final class PosixEventDriver(Loop : PosixEventLoop) : EventDriver { else alias SignalsDriver = DummyEventDriverSignals!Loop; alias TimerDriver = LoopTimeoutTimerDriver; alias SocketsDriver = PosixEventDriverSockets!Loop; - /*version (linux) alias DNSDriver = EventDriverDNS_GAIA!(EventsDriver, SignalsDriver); - else*/ alias DNSDriver = EventDriverDNS_GAI!(EventsDriver, SignalsDriver); + version (Windows) alias DNSDriver = EventDriverDNS_GHBN!(EventsDriver, SignalsDriver); + //version (linux) alias DNSDriver = EventDriverDNS_GAIA!(EventsDriver, SignalsDriver); + else alias DNSDriver = EventDriverDNS_GAI!(EventsDriver, SignalsDriver); alias FileDriver = ThreadedFileEventDriver!EventsDriver; version (linux) alias WatcherDriver = InotifyEventDriverWatchers!Loop; else alias WatcherDriver = PosixEventDriverWatchers!Loop; @@ -830,7 +832,8 @@ final class PosixEventDriverSockets(Loop : PosixEventLoop) : EventDriverSockets } -/// getaddrinfo_a based asynchronous lookups +/// getaddrinfo+thread based lookup - does not support true cancellation +version (Posix) final class EventDriverDNS_GAI(Events : EventDriverEvents, Signals : EventDriverSignals) : EventDriverDNS { import std.parallelism : task, taskPool; import std.string : toStringz; @@ -930,7 +933,7 @@ final class EventDriverDNS_GAI(Events : EventDriverEvents, Signals : EventDriver } -/// getaddrinfo+thread based lookup - does not support true cancellation +/// getaddrinfo_a based asynchronous lookups final class EventDriverDNS_GAIA(Events : EventDriverEvents, Signals : EventDriverSignals) : EventDriverDNS { import core.sys.posix.signal : SIGEV_SIGNAL, SIGRTMIN, sigevent; @@ -1035,7 +1038,71 @@ version (linux) extern(C) { int gai_cancel(gaicb *req); } -private void passToDNSCallback(DNSLookupID id, scope DNSLookupCallback cb, DNSStatus status, addrinfo* ai_orig) + +/// ghbn based lookup - does not support cancellation and blocks the thread! +final class EventDriverDNS_GHBN(Events : EventDriverEvents, Signals : EventDriverSignals) : EventDriverDNS { + import std.parallelism : task, taskPool; + import std.string : toStringz; + + private { + static struct Lookup { + DNSLookupCallback callback; + bool success; + int retcode; + string name; + } + size_t m_maxHandle; + } + + this(Events events, Signals signals) + { + } + + void dispose() + { + } + + override DNSLookupID lookupHost(string name, DNSLookupCallback on_lookup_finished) + { + import std.string : toStringz; + + auto handle = DNSLookupID(m_maxHandle++); + + auto he = () @trusted { return gethostbyname(name.toStringz); } (); + if (he is null) { + on_lookup_finished(handle, DNSStatus.error, null); + return handle; + } + switch (he.h_addrtype) { + default: assert(false, "Invalid address family returned from host lookup."); + case AF_INET: { + sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_addr = () @trusted { return *cast(in_addr*)he.h_addr_list[0]; } (); + scope addr = new RefAddress(() @trusted { return cast(sockaddr*)&sa; } (), sa.sizeof); + RefAddress[1] aa; + aa[0] = addr; + on_lookup_finished(handle, DNSStatus.ok, aa); + } break; + case AF_INET6: { + sockaddr_in6 sa; + sa.sin6_family = AF_INET6; + sa.sin6_addr = () @trusted { return *cast(in6_addr*)he.h_addr_list[0]; } (); + scope addr = new RefAddress(() @trusted { return cast(sockaddr*)&sa; } (), sa.sizeof); + RefAddress[1] aa; + aa[0] = addr; + on_lookup_finished(handle, DNSStatus.ok, aa); + } break; + } + + return handle; + } + + override void cancelLookup(DNSLookupID) {} +} + + +private void passToDNSCallback()(DNSLookupID id, scope DNSLookupCallback cb, DNSStatus status, addrinfo* ai_orig) @trusted nothrow { import std.typecons : scoped;