1 module yu.eventloop.common;
2 
3 //import core.memory;
4 
5 public import std.experimental.logger;
6 import yu.memory.allocator;
7 
8 static if (CustomTimer) {
9     public import yu.timer.timingwheeltimer;
10 
11     alias ETimerWheel = ITimingWheel!IAllocator;
12     alias EWheelTimer = ETimerWheel.WheelTimer;
13 }
14 
15 enum IO_MODE {
16     epoll,
17     kqueue,
18     iocp,
19     select,
20     poll,
21     port,
22     none
23 }
24 
25 enum CustomTimerTimeOut = 50; // 50ms 精确
26 enum CustomTimerWheelSize = 20; // 轮子数量
27 
28 version (FreeBSD) {
29     enum IO_MODE IOMode = IO_MODE.kqueue;
30     enum CustomTimer = false;
31 } else version (OpenBSD) {
32     enum IO_MODE IOMode = IO_MODE.kqueue;
33     enum CustomTimer = false;
34 } else version (NetBSD) {
35     enum IO_MODE IOMode = IO_MODE.kqueue;
36     enum CustomTimer = false;
37 } else version (OSX) {
38     enum IO_MODE IOMode = IO_MODE.kqueue;
39     enum CustomTimer = false;
40 } else version (linux) {
41     enum IO_MODE IOMode = IO_MODE.epoll;
42     enum CustomTimer = false;
43 } else version (Windows) {
44     enum IO_MODE IOMode = IO_MODE.iocp;
45     enum CustomTimer = true;
46 } else {
47     static assert(0, "not suport this  platform !");
48 }
49 
50 alias CallBack = void delegate() nothrow;
51 
52 enum AsynType {
53     ACCEPT,
54     TCP,
55     UDP,
56     EVENT,
57     TIMER
58 }
59 
60 interface EventCallInterface {
61     void onWrite() nothrow;
62     void onRead() nothrow;
63     void onClose() nothrow;
64 }
65 
66 struct AsyncEvent {
67     import std.socket;
68 
69     this(AsynType type, EventCallInterface obj, socket_t fd = socket_t.init,
70         bool enread = true, bool enwrite = false, bool etMode = false, bool oneShot = false) {
71         this._type = type;
72         this._obj = obj;
73         this._fd = fd;
74         this.enRead = enread;
75         this.enWrite = enwrite;
76         this.etMode = etMode;
77         this.oneShot = oneShot;
78     }
79 
80     @disable this();
81     @disable this(this);
82 
83     ~this() {
84         rmNextPrev();
85     }
86 
87     pragma(inline, true) @property obj() {
88         return _obj;
89     }
90 
91     pragma(inline, true) @property type() {
92         return _type;
93     }
94 
95     pragma(inline, true) @property fd() {
96         return _fd;
97     }
98 
99     bool enRead = true;
100     bool enWrite = false;
101     bool etMode = false;
102     bool oneShot = false;
103 
104     pragma(inline, true) @property isActive() {
105         return _isActive;
106     }
107 
108 package(yu):
109     static if (IOMode == IOMode.kqueue || CustomTimer) {
110         long timeOut;
111     }
112 package(yu):
113     static if (IOMode == IOMode.iocp) {
114         uint readLen;
115         uint writeLen;
116     }
117 
118 package(yu.eventloop):
119     pragma(inline) @property isActive(bool active) {
120         _isActive = active;
121     }
122 
123     static if (CustomTimer) {
124         import yu.timer.timingwheeltimer;
125         import std.experimental.allocator;
126 
127         EWheelTimer timer;
128     }
129 
130     @trusted void rmNextPrev() @nogc nothrow {
131         if (next)
132             next.prev = prev;
133         if (prev)
134             prev.next = next;
135         next = null;
136         prev = null;
137     }
138 
139     AsyncEvent* next = null;
140     AsyncEvent* prev = null;
141 
142     socket_t _fd = socket_t.init;
143 private:
144     EventCallInterface _obj;
145     AsynType _type;
146     bool _isActive = false;
147 }
148 
149 static if (CustomTimer) {
150     enum CustomTimer_Next_TimeOut = cast(long)(CustomTimerTimeOut * (2.0 / 3.0));
151 }