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 	@property fd_t id() const {
51 		return m_evId;
52 	}
53 
54 package:
55 	version(Posix) mixin EvInfoMixins;
56 
57 	void handler() {
58 		try m_evh();
59 		catch {}
60 		return;
61 	}
62 }
63 
64 package struct NotifierHandler {
65 	AsyncNotifier ctxt;
66 	void function(AsyncNotifier) fct;
67 	
68 	void opCall() {
69 		assert(ctxt !is null);
70 		fct(ctxt);
71 		return;
72 	}
73 }