OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef BIN_EVENTHANDLER_LINUX_H_ | 5 #ifndef BIN_EVENTHANDLER_LINUX_H_ |
6 #define BIN_EVENTHANDLER_LINUX_H_ | 6 #define BIN_EVENTHANDLER_LINUX_H_ |
7 | 7 |
8 #if !defined(BIN_EVENTHANDLER_H_) | 8 #if !defined(BIN_EVENTHANDLER_H_) |
9 #error Do not include eventhandler_linux.h directly; use eventhandler.h instead. | 9 #error Do not include eventhandler_linux.h directly; use eventhandler.h instead. |
10 #endif | 10 #endif |
(...skipping 10 matching lines...) Expand all Loading... | |
21 namespace dart { | 21 namespace dart { |
22 namespace bin { | 22 namespace bin { |
23 | 23 |
24 class InterruptMessage { | 24 class InterruptMessage { |
25 public: | 25 public: |
26 intptr_t id; | 26 intptr_t id; |
27 Dart_Port dart_port; | 27 Dart_Port dart_port; |
28 int64_t data; | 28 int64_t data; |
29 }; | 29 }; |
30 | 30 |
31 template<typename T> | |
32 class CircularLinkedList { | |
33 public: | |
34 CircularLinkedList() : head_(NULL) {} | |
31 | 35 |
36 bool Add(T t) { | |
37 Entry* e = new Entry(t); | |
38 if (head_ == NULL) { | |
39 e->next_ = e; | |
40 e->prev_ = e; | |
41 head_ = e; | |
42 return true; | |
43 } else { | |
Lasse Reichstein Nielsen
2014/05/06 09:04:20
Add comment, either on method or here:
Adds entry
Anders Johnsen
2014/05/06 12:34:32
Done.
| |
44 e->prev_ = head_->prev_; | |
45 e->next_ = head_; | |
46 e->prev_->next_ = e; | |
47 e->next_->prev_ = e; | |
Lasse Reichstein Nielsen
2014/05/06 09:04:20
Just:
head_->prev = e;
Anders Johnsen
2014/05/06 12:34:32
Done.
| |
48 return false; | |
49 } | |
50 } | |
51 | |
52 void RemoveHead() { | |
53 Entry* e = head_; | |
54 if (e->next_ == e) { | |
55 head_ = NULL; | |
56 } else { | |
57 e->prev_->next_ = e->next_; | |
58 e->next_->prev_ = e->prev_; | |
59 head_ = e->next_; | |
60 } | |
61 delete e; | |
62 } | |
63 | |
64 T head() const { return head_->t; } | |
65 | |
66 bool HasHead() { | |
67 return head_ != NULL; | |
68 } | |
69 | |
70 void MoveNext() { | |
Lasse Reichstein Nielsen
2014/05/06 09:04:20
Could this be named something with "rotate"?
Anders Johnsen
2014/05/06 12:34:32
Done.
| |
71 head_ = head_->next_; | |
72 } | |
73 | |
74 private: | |
75 struct Entry { | |
76 explicit Entry(const T& t) : t(t) {} | |
77 const T t; | |
78 Entry* next_; | |
79 Entry* prev_; | |
80 }; | |
81 | |
82 Entry* head_; | |
83 }; | |
84 | |
85 | |
86 class ListeningSocketData; | |
32 class SocketData { | 87 class SocketData { |
33 public: | 88 public: |
34 explicit SocketData(intptr_t fd) : fd_(fd), port_(0), mask_(0), tokens_(16) { | 89 explicit SocketData(intptr_t fd) |
90 : fd_(fd), port_(0), mask_(0), tokens_(16) { | |
35 ASSERT(fd_ != -1); | 91 ASSERT(fd_ != -1); |
36 } | 92 } |
37 | 93 |
94 virtual ~SocketData() { | |
95 } | |
96 | |
38 intptr_t GetPollEvents(); | 97 intptr_t GetPollEvents(); |
39 | 98 |
40 void Close() { | 99 void Close() { |
41 port_ = 0; | 100 port_ = 0; |
42 mask_ = 0; | 101 mask_ = 0; |
43 VOID_TEMP_FAILURE_RETRY(close(fd_)); | 102 VOID_TEMP_FAILURE_RETRY(close(fd_)); |
44 fd_ = -1; | 103 fd_ = -1; |
45 } | 104 } |
46 | 105 |
47 void SetPortAndMask(Dart_Port port, intptr_t mask) { | 106 void SetMask(intptr_t mask) { |
48 ASSERT(fd_ != -1); | 107 ASSERT(fd_ != -1); |
49 port_ = port; | |
50 mask_ = mask; | 108 mask_ = mask; |
51 } | 109 } |
52 | 110 |
53 intptr_t fd() { return fd_; } | 111 intptr_t fd() { return fd_; } |
54 Dart_Port port() { return port_; } | 112 virtual Dart_Port port() { return port_; } |
55 | 113 |
56 bool IsListeningSocket() { return (mask_ & (1 << kListeningSocket)) != 0; } | 114 virtual bool IsListeningSocket() const { return false; } |
115 | |
116 virtual bool AddPort(Dart_Port port) { | |
117 ASSERT(port_ = 0); | |
118 port_ = port; | |
119 return true; | |
120 } | |
121 | |
122 virtual bool RemovePort(Dart_Port port) { | |
123 ASSERT(port_ == port); | |
124 return true; | |
125 } | |
57 | 126 |
58 // Returns true if the last token was taken. | 127 // Returns true if the last token was taken. |
59 bool TakeToken() { | 128 virtual bool TakeToken() { |
60 ASSERT(tokens_ > 0); | 129 ASSERT(tokens_ > 0); |
61 tokens_--; | 130 tokens_--; |
62 return tokens_ == 0; | 131 return tokens_ == 0; |
63 } | 132 } |
64 | 133 |
65 // Returns true if the tokens was 0 before adding. | 134 // Returns true if the tokens was 0 before adding. |
66 bool ReturnToken() { | 135 virtual bool ReturnToken(Dart_Port port, int count) { |
136 ASSERT(port_ == port); | |
67 ASSERT(tokens_ >= 0); | 137 ASSERT(tokens_ >= 0); |
68 tokens_++; | 138 bool was_empty = tokens_ == 0; |
69 return tokens_ == 1; | 139 tokens_ += count; |
140 return was_empty; | |
70 } | 141 } |
71 | 142 |
72 private: | 143 bool HasTokens() const { return tokens_ > 0; } |
144 | |
145 protected: | |
73 intptr_t fd_; | 146 intptr_t fd_; |
74 Dart_Port port_; | 147 Dart_Port port_; |
75 intptr_t mask_; | 148 intptr_t mask_; |
76 int tokens_; | 149 int tokens_; |
77 }; | 150 }; |
78 | 151 |
79 | 152 |
153 class ListeningSocketData : public SocketData { | |
154 private: | |
155 static const int kTokenCount = 4; | |
156 | |
157 static bool SamePortValue(void* key1, void* key2) { | |
158 return reinterpret_cast<Dart_Port>(key1) == | |
159 reinterpret_cast<Dart_Port>(key2); | |
160 } | |
161 | |
162 static uint32_t GetHashmapHashFromPort(Dart_Port port) { | |
163 return static_cast<uint32_t>(port & 0xFFFFFFFF); | |
Lasse Reichstein Nielsen
2014/05/06 09:04:20
Why the '& 0xFFFFFFFF' ?
Casting an int64_t to uin
Anders Johnsen
2014/05/06 12:34:32
Not sure, review feedback from sgjesse. Sgjesse?
| |
164 } | |
165 | |
166 static void* GetHashmapKeyFromPort(Dart_Port port) { | |
167 return reinterpret_cast<void*>(port); | |
168 } | |
169 | |
170 public: | |
171 explicit ListeningSocketData(intptr_t fd) | |
172 : SocketData(fd), | |
173 tokens_map_(&SamePortValue, 4) {} | |
174 | |
175 bool IsListeningSocket() const { return true; } | |
176 | |
177 bool AddPort(Dart_Port port) { | |
178 HashMap::Entry* entry = tokens_map_.Lookup( | |
179 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), true); | |
180 entry->value = reinterpret_cast<void*>(kTokenCount); | |
181 return live_ports_.Add(port); | |
182 } | |
183 | |
184 virtual bool RemovePort(Dart_Port port) { | |
185 HashMap::Entry* entry = tokens_map_.Lookup( | |
186 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false); | |
187 ASSERT(entry != NULL); | |
188 intptr_t tokens = reinterpret_cast<intptr_t>(entry->value); | |
189 if (tokens == 0) { | |
190 while (idle_ports_.head() != port) { | |
191 idle_ports_.MoveNext(); | |
192 } | |
193 idle_ports_.RemoveHead(); | |
194 } else { | |
195 while (live_ports_.head() != port) { | |
196 live_ports_.MoveNext(); | |
197 } | |
198 live_ports_.RemoveHead(); | |
199 } | |
200 tokens_map_.Remove( | |
201 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port)); | |
202 return !live_ports_.HasHead(); | |
203 } | |
204 | |
205 bool TakeToken() { | |
206 ASSERT(live_ports_.HasHead()); | |
207 Dart_Port port = live_ports_.head(); | |
208 HashMap::Entry* entry = tokens_map_.Lookup( | |
209 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false); | |
210 ASSERT(entry != NULL); | |
211 intptr_t tokens = reinterpret_cast<intptr_t>(entry->value); | |
212 tokens--; | |
213 entry->value = reinterpret_cast<void*>(tokens); | |
214 if (tokens == 0) { | |
215 live_ports_.RemoveHead(); | |
216 idle_ports_.Add(port); | |
217 if (!live_ports_.HasHead()) { | |
218 return true; | |
219 } | |
220 } else { | |
221 live_ports_.MoveNext(); | |
222 } | |
223 return false; | |
224 } | |
225 | |
226 Dart_Port port() { return live_ports_.head(); } | |
227 | |
228 bool ReturnToken(Dart_Port port, int count) { | |
229 HashMap::Entry* entry = tokens_map_.Lookup( | |
230 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false); | |
231 ASSERT(entry != NULL); | |
232 intptr_t tokens = reinterpret_cast<intptr_t>(entry->value); | |
233 tokens += count; | |
234 entry->value = reinterpret_cast<void*>(tokens); | |
235 if (tokens == count) { | |
236 // Return to live_ports_. | |
237 while (idle_ports_.head() != port) { | |
238 idle_ports_.MoveNext(); | |
239 } | |
240 idle_ports_.RemoveHead(); | |
241 bool was_empty = !live_ports_.HasHead(); | |
242 live_ports_.Add(port); | |
243 return was_empty; | |
244 } | |
245 return false; | |
246 } | |
247 | |
248 private: | |
249 CircularLinkedList<Dart_Port> live_ports_; | |
250 CircularLinkedList<Dart_Port> idle_ports_; | |
251 HashMap tokens_map_; | |
252 }; | |
253 | |
254 | |
80 class EventHandlerImplementation { | 255 class EventHandlerImplementation { |
81 public: | 256 public: |
82 EventHandlerImplementation(); | 257 EventHandlerImplementation(); |
83 ~EventHandlerImplementation(); | 258 ~EventHandlerImplementation(); |
84 | 259 |
85 // Gets the socket data structure for a given file | 260 // Gets the socket data structure for a given file |
86 // descriptor. Creates a new one if one is not found. | 261 // descriptor. Creates a new one if one is not found. |
87 SocketData* GetSocketData(intptr_t fd); | 262 SocketData* GetSocketData(intptr_t fd, bool is_listening); |
88 void SendData(intptr_t id, Dart_Port dart_port, int64_t data); | 263 void SendData(intptr_t id, Dart_Port dart_port, int64_t data); |
89 void Start(EventHandler* handler); | 264 void Start(EventHandler* handler); |
90 void Shutdown(); | 265 void Shutdown(); |
91 | 266 |
92 private: | 267 private: |
93 void HandleEvents(struct epoll_event* events, int size); | 268 void HandleEvents(struct epoll_event* events, int size); |
94 static void Poll(uword args); | 269 static void Poll(uword args); |
95 void WakeupHandler(intptr_t id, Dart_Port dart_port, int64_t data); | 270 void WakeupHandler(intptr_t id, Dart_Port dart_port, int64_t data); |
96 void HandleInterruptFd(); | 271 void HandleInterruptFd(); |
97 void SetPort(intptr_t fd, Dart_Port dart_port, intptr_t mask); | 272 void SetPort(intptr_t fd, Dart_Port dart_port, intptr_t mask); |
98 intptr_t GetPollEvents(intptr_t events, SocketData* sd); | 273 intptr_t GetPollEvents(intptr_t events, SocketData* sd); |
99 static void* GetHashmapKeyFromFd(intptr_t fd); | 274 static void* GetHashmapKeyFromFd(intptr_t fd); |
100 static uint32_t GetHashmapHashFromFd(intptr_t fd); | 275 static uint32_t GetHashmapHashFromFd(intptr_t fd); |
101 | 276 |
102 HashMap socket_map_; | 277 HashMap socket_map_; |
103 TimeoutQueue timeout_queue_; | 278 TimeoutQueue timeout_queue_; |
104 bool shutdown_; | 279 bool shutdown_; |
105 int interrupt_fds_[2]; | 280 int interrupt_fds_[2]; |
106 int epoll_fd_; | 281 int epoll_fd_; |
107 int timer_fd_; | 282 int timer_fd_; |
108 }; | 283 }; |
109 | 284 |
110 } // namespace bin | 285 } // namespace bin |
111 } // namespace dart | 286 } // namespace dart |
112 | 287 |
113 #endif // BIN_EVENTHANDLER_LINUX_H_ | 288 #endif // BIN_EVENTHANDLER_LINUX_H_ |
OLD | NEW |