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 }