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 }