1 /** 2 WinAPI based event driver implementation. 3 4 This driver uses overlapped I/O to model asynchronous I/O operations 5 efficiently. The driver's event loop processes UI messages, so that 6 it integrates with GUI applications transparently. 7 */ 8 module eventcore.drivers.winapi.driver; 9 10 version (Windows): 11 12 import eventcore.driver; 13 import eventcore.drivers.timer; 14 import eventcore.drivers.winapi.core; 15 import eventcore.drivers.winapi.dns; 16 import eventcore.drivers.winapi.events; 17 import eventcore.drivers.winapi.files; 18 import eventcore.drivers.winapi.pipes; 19 import eventcore.drivers.winapi.processes; 20 import eventcore.drivers.winapi.signals; 21 import eventcore.drivers.winapi.sockets; 22 import eventcore.drivers.winapi.watchers; 23 import eventcore.internal.utils : mallocT, freeT; 24 import core.sys.windows.windows; 25 26 static assert(HANDLE.sizeof <= FD.BaseType.sizeof); 27 static assert(FD(cast(size_t)INVALID_HANDLE_VALUE, 0) == FD.init); 28 29 30 final class WinAPIEventDriver : EventDriver { 31 private { 32 WinAPIEventDriverCore m_core; 33 WinAPIEventDriverFiles m_files; 34 WinAPIEventDriverSockets m_sockets; 35 WinAPIEventDriverDNS m_dns; 36 LoopTimeoutTimerDriver m_timers; 37 WinAPIEventDriverEvents m_events; 38 WinAPIEventDriverSignals m_signals; 39 WinAPIEventDriverWatchers m_watchers; 40 WinAPIEventDriverProcesses m_processes; 41 WinAPIEventDriverPipes m_pipes; 42 } 43 44 static WinAPIEventDriver threadInstance; 45 46 this() 47 @safe nothrow @nogc { 48 assert(threadInstance is null); 49 threadInstance = this; 50 51 import std.exception : enforce; 52 53 WSADATA wd; 54 55 auto res = () @trusted { return WSAStartup(0x0202, &wd); } (); 56 assert(res == 0, "Failed to initialize WinSock"); 57 58 m_signals = mallocT!WinAPIEventDriverSignals(); 59 m_timers = mallocT!LoopTimeoutTimerDriver(); 60 m_core = mallocT!WinAPIEventDriverCore(m_timers); 61 m_events = mallocT!WinAPIEventDriverEvents(m_core); 62 m_files = mallocT!WinAPIEventDriverFiles(m_core); 63 m_sockets = mallocT!WinAPIEventDriverSockets(m_core); 64 m_pipes = mallocT!WinAPIEventDriverPipes(); 65 m_dns = mallocT!WinAPIEventDriverDNS(); 66 m_watchers = mallocT!WinAPIEventDriverWatchers(m_core); 67 m_processes = mallocT!WinAPIEventDriverProcesses(); 68 } 69 70 @safe: /*@nogc:*/ nothrow: 71 72 override @property inout(WinAPIEventDriverCore) core() inout { return m_core; } 73 override @property shared(inout(WinAPIEventDriverCore)) core() inout shared { return m_core; } 74 override @property inout(WinAPIEventDriverFiles) files() inout { return m_files; } 75 override @property inout(WinAPIEventDriverSockets) sockets() inout { return m_sockets; } 76 override @property inout(WinAPIEventDriverDNS) dns() inout { return m_dns; } 77 override @property inout(LoopTimeoutTimerDriver) timers() inout { return m_timers; } 78 override @property inout(WinAPIEventDriverEvents) events() inout { return m_events; } 79 override @property shared(inout(WinAPIEventDriverEvents)) events() inout shared { return m_events; } 80 override @property inout(WinAPIEventDriverSignals) signals() inout { return m_signals; } 81 override @property inout(WinAPIEventDriverWatchers) watchers() inout { return m_watchers; } 82 override @property inout(WinAPIEventDriverProcesses) processes() inout { return m_processes; } 83 override @property inout(WinAPIEventDriverPipes) pipes() inout { return m_pipes; } 84 85 override bool dispose() 86 { 87 if (!m_events) return true; 88 89 if (m_core.checkForLeakedHandles()) return false; 90 if (m_events.checkForLeakedHandles()) return false; 91 if (m_sockets.checkForLeakedHandles()) return false; 92 93 m_events.dispose(); 94 m_core.dispose(); 95 assert(threadInstance !is null); 96 threadInstance = null; 97 98 try () @trusted { 99 freeT(m_processes); 100 freeT(m_watchers); 101 freeT(m_dns); 102 freeT(m_pipes); 103 freeT(m_sockets); 104 freeT(m_files); 105 freeT(m_events); 106 freeT(m_core); 107 freeT(m_timers); 108 freeT(m_signals); 109 } (); 110 catch (Exception e) assert(false, e.msg); 111 112 return true; 113 } 114 }