1 module libasync.notifier; 2 3 import libasync.types; 4 import libasync.events; 5 6 /// Thread-local event dispatcher/handler, used to wake up the associated 7 /// callback in a new call stack originating from the event loop. 8 final class AsyncNotifier 9 { 10 void delegate() m_evh; 11 nothrow: 12 private: 13 EventLoop m_evLoop; 14 fd_t m_evId; 15 version(Posix) static if (EPOLL) shared ushort m_owner; 16 17 public: 18 this(EventLoop evl) 19 in { 20 assert(evl !is null); 21 } 22 body { 23 m_evLoop = evl; 24 } 25 26 mixin DefStatus; 27 28 /// Starts the notifier with the associated delegate (handler) 29 bool run(void delegate() del) { 30 m_evh = cast(void delegate()) del; 31 m_evId = m_evLoop.run(this); 32 if (m_evId != fd_t.init) 33 return true; 34 else 35 return false; 36 } 37 38 /// Cleans up associated resources. 39 bool kill() 40 { 41 return m_evLoop.kill(this); 42 } 43 44 /// Enqueues a call to the handler originating from the thread-local event loop. 45 bool trigger() 46 { 47 return m_evLoop.notify(m_evId, this); 48 } 49 50 package: 51 52 version(Posix) mixin EvInfoMixins; 53 54 @property id() const { 55 return m_evId; 56 } 57 58 void handler() { 59 try m_evh(); 60 catch {} 61 return; 62 } 63 } 64 65 package struct NotifierHandler { 66 AsyncNotifier ctxt; 67 void function(AsyncNotifier) fct; 68 69 void opCall() { 70 assert(ctxt !is null); 71 fct(ctxt); 72 return; 73 } 74 }