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