1 module dast.async.eventloop;
2 
3 import dast.async.selector;
4 @safe:
5 
6 class EventLoop {
7 	mixin Selector;
8 
9 	private bool running;
10 
11 	void run() {
12 		running = true;
13 		do {
14 			onWeakUp();
15 		}
16 		while (running);
17 	}
18 
19 	void stop() nothrow {
20 		running = false;
21 		static if (is(typeof(weakUp())))
22 			weakUp();
23 	}
24 }
25 
26 class EventExecutor : EventLoop {
27 	import core.thread,
28 	tame.fixed.queue;
29 
30 	private Queue!(Fiber, 64) tasks;
31 	private Fiber task;
32 
33 	void queueTask(Fiber fiber) {
34 		if (tasks.full)
35 			throw new Exception("EventExecutor: tasks queue is full");
36 		tasks.push(fiber);
37 	}
38 
39 	override void run() @trusted {
40 		task = new Fiber(&super.onWeakUp);
41 		super.run();
42 	}
43 
44 	override void onWeakUp() @trusted {
45 		if (task.state == Fiber.State.TERM)
46 			task.reset();
47 		task.call();
48 		for (uint count = tasks.size; count--;) {
49 			auto t = tasks.pop();
50 			if (t.state == Fiber.State.HOLD) {
51 				t.call();
52 				if (t.state == Fiber.State.HOLD) {
53 					tasks.push(t);
54 				}
55 			}
56 		}
57 	}
58 }