1 module dast.async.core; 2 3 import std.array, 4 tame.fixed.queue; 5 public import dast.async.eventloop : EventLoop; 6 7 @safe: 8 alias SimpleHandler = void delegate() nothrow, 9 ErrorHandler = void delegate(in char[] msg) nothrow, 10 RecvHandler = void delegate(in ubyte[] data), 11 DataSentHandler = void delegate(in void[] data) nothrow; 12 13 abstract class SocketChannel { 14 ErrorHandler onError; 15 16 package WF flags; 17 const WatcherType type; 18 protected bool _isReg; 19 pure nothrow @nogc { 20 @property { 21 final handle() const => _socket.handle; 22 23 final socket() => _socket; 24 25 final bool isRegistered() const => _isReg; 26 } 27 28 this(EventLoop loop, WatcherType type = WT.Event) { 29 _loop = loop; 30 this.type = type; 31 onError = (msg) { 32 debug (Log) { 33 try 34 error(msg); 35 catch (Exception) { 36 } 37 } 38 }; 39 } 40 } 41 42 void onRead() { 43 assert(0, "unimplemented"); 44 } 45 46 nothrow: 47 void close() { 48 if (!_isReg) 49 assert(0, text("The watcher(fd=", handle, ") has already been closed")); 50 _isReg = false; 51 static if(is(typeof(_loop.unregister(this)))) 52 _loop.unregister(this); 53 _loop = EventLoop.init; 54 debug (Log) 55 trace("channel closed...", handle); 56 } 57 58 protected: 59 @property final void socket(Socket s) { 60 version (Posix) { 61 s.blocking = false; 62 } 63 _socket = s; 64 debug (Log) 65 trace("new socket fd: ", handle); 66 } 67 68 EventLoop _loop; 69 Socket _socket; 70 } 71 72 //alias WriteQueue = Queue!(const(void)[], 32, true); 73 74 enum WatcherType : ubyte { 75 None, 76 Accept, 77 TCP, 78 //UDP, 79 Timer = 4, 80 Event, 81 } 82 83 enum WatchFlag : uint { 84 None, 85 Read = 0x001, 86 Write = 0x004, 87 ReadWrite = Read | Write, 88 89 OneShot = 0x0010, 90 ETMode = 0x0020, 91 OneShotET = OneShot | ETMode, 92 } 93 94 package: 95 debug (Log) import tame.logger; 96 import tame.net.socket, 97 std.conv : text; 98 99 alias WT = WatcherType, 100 WF = WatchFlag, 101 BUF = uninitializedArray!(ubyte[], size_t);