Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(420)

Side by Side Diff: dart/runtime/bin/eventhandler.h

Issue 879353003: Introduce optional 'bool shared' parameter to ServerSocket.bind() ... (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Part 3: Other platforms (preliminary) Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_H_ 5 #ifndef BIN_EVENTHANDLER_H_
6 #define BIN_EVENTHANDLER_H_ 6 #define BIN_EVENTHANDLER_H_
7 7
8 #include "bin/builtin.h" 8 #include "bin/builtin.h"
9 #include "bin/isolate_data.h" 9 #include "bin/isolate_data.h"
10 10
11 #include "platform/hashmap.h"
12
11 namespace dart { 13 namespace dart {
12 namespace bin { 14 namespace bin {
13 15
14 // Flags used to provide information and actions to the eventhandler 16 // Flags used to provide information and actions to the eventhandler
15 // when sending a message about a file descriptor. These flags should 17 // when sending a message about a file descriptor. These flags should
16 // be kept in sync with the constants in socket_impl.dart. For more 18 // be kept in sync with the constants in socket_impl.dart. For more
17 // information see the comments in socket_impl.dart 19 // information see the comments in socket_impl.dart
18 enum MessageFlags { 20 enum MessageFlags {
19 kInEvent = 0, 21 kInEvent = 0,
20 kOutEvent = 1, 22 kOutEvent = 1,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 UpdateTimeout(CurrentPort(), -1); 89 UpdateTimeout(CurrentPort(), -1);
88 } 90 }
89 91
90 void UpdateTimeout(Dart_Port port, int64_t timeout); 92 void UpdateTimeout(Dart_Port port, int64_t timeout);
91 93
92 private: 94 private:
93 Timeout* next_timeout_; 95 Timeout* next_timeout_;
94 Timeout* timeouts_; 96 Timeout* timeouts_;
95 }; 97 };
96 98
99
100 template<typename T>
101 class CircularLinkedList {
102 public:
103 CircularLinkedList() : head_(NULL) {}
104
105 // Returns true if the list was empty.
106 bool Add(T t) {
107 Entry* e = new Entry(t);
108 if (head_ == NULL) {
109 // Empty list, make e head, and point to itself.
110 e->next_ = e;
111 e->prev_ = e;
112 head_ = e;
113 return true;
114 } else {
115 // Insert e as the last element in the list.
116 e->prev_ = head_->prev_;
117 e->next_ = head_;
118 e->prev_->next_ = e;
119 head_->prev_ = e;
120 return false;
121 }
122 }
123
124 void RemoveHead() {
125 Entry* e = head_;
126 if (e->next_ == e) {
127 head_ = NULL;
128 } else {
129 e->prev_->next_ = e->next_;
130 e->next_->prev_ = e->prev_;
131 head_ = e->next_;
132 }
133 delete e;
134 }
135
136 T head() const { return head_->t; }
137
138 bool HasHead() const {
139 return head_ != NULL;
140 }
141
142 void Rotate() {
143 head_ = head_->next_;
144 }
145
146 private:
147 struct Entry {
148 explicit Entry(const T& t) : t(t) {}
149 const T t;
150 Entry* next_;
151 Entry* prev_;
152 };
153
154 Entry* head_;
155 };
156
157
158 class DescriptorInfo {
159 public:
160 explicit DescriptorInfo(intptr_t fd) : fd_(fd), mask_(0) {
161 ASSERT(fd_ != -1);
162 }
163
164 virtual ~DescriptorInfo() {
165 mask_ = 0;
166 }
167
168 intptr_t fd() { return fd_; }
169
170
171 // Type of socket.
172
173 virtual bool IsListeningSocket() const = 0;
174
175
176 // Ports.
177
178 virtual bool AddPort(Dart_Port port) = 0;
179
180 virtual bool RemovePort(Dart_Port port) = 0;
181
182 // Returns the next port which should be used for sending events to.
183 virtual Dart_Port NextPort() = 0;
184
185 virtual bool HasNextPort() = 0;
186
187
188 // Tokens.
189
190 // Returns true if the last token was taken.
191 virtual bool TakeToken() = 0;
192
193 // Returns true if the tokens was 0 before adding.
194 virtual bool ReturnTokens(Dart_Port port, int count) = 0;
195
196 // Returns true if for any registired Dart_port tokens are available.
197 virtual bool HasTokens() const = 0;
198
199
200 // Other.
201
202 virtual void Close() = 0;
203
204 void SetMask(intptr_t mask) {
205 mask_ = mask;
206 }
207
208 intptr_t Mask() { return mask_; }
209
210 protected:
211 intptr_t fd_;
212 // Mask of events to report through the port.
213 intptr_t mask_;
214 };
215
216
217 // Describes a OS descriptor (e.g. file descriptor on linux or HANDLE on
218 // windows) which is connected to a single Dart_Port.
219 //
220 // Subclasses of this class can be e.g. connected tcp sockets
221 template<typename SI>
222 class DescriptorInfoSingle : public SI {
223 public:
224 explicit DescriptorInfoSingle(intptr_t fd) : SI(fd), port_(0), tokens_(16) {
225 }
226
227 virtual ~DescriptorInfoSingle() { }
228
229 virtual bool IsListeningSocket() const { return false; }
230
231 virtual bool AddPort(Dart_Port port) {
232 ASSERT(port_ == 0 || port == port_);
Søren Gjesse 2015/02/02 10:56:14 This assert looks strange. Are we adding the same
kustermann 2015/02/03 10:45:35 I think so, I've observed this on windows I think.
233 port_ = port;
234 return true;
235 }
236
237 virtual bool RemovePort(Dart_Port port) {
238 ASSERT(port_ == 0 || port_ == port);
Søren Gjesse 2015/02/02 10:56:14 Again, are we removing a port which is not added?
kustermann 2015/02/03 10:45:35 ditto. I'll add a TODO. If you want, I can also v
239 port_ = 0;
240 return true;
241 }
242
243 virtual Dart_Port NextPort() {
244 ASSERT(port_ != 0);
245 return port_;
246 }
247
248 virtual bool HasNextPort() {
249 return port_ != 0;
250 }
251
252 virtual bool TakeToken() {
253 ASSERT(tokens_ > 0);
254 tokens_--;
255 return tokens_ == 0;
256 }
257
258 virtual bool ReturnTokens(Dart_Port port, int count) {
259 ASSERT(port_ == port);
260 ASSERT(tokens_ >= 0);
261 bool was_empty = tokens_ == 0;
262 tokens_ += count;
263 return was_empty;
264 }
265
266 virtual bool HasTokens() const { return tokens_ > 0; }
267
268 virtual void Close() {
269 SI::Close();
270 }
271
272 private:
273 Dart_Port port_;
274 int tokens_;
275 };
276
277
278 // Describes a OS descriptor (e.g. file descriptor on linux or HANDLE on
279 // windows) which is connected to multiple Dart_Port's.
280 //
281 // Subclasses of this class can be e.g. a listening socket which multiple
282 // isolates are listening on.
283 template<typename SI>
284 class DescriptorInfoMultiple : public SI {
285 private:
286 static const int kTokenCount = 4;
287
288 static bool SamePortValue(void* key1, void* key2) {
289 return reinterpret_cast<Dart_Port>(key1) ==
290 reinterpret_cast<Dart_Port>(key2);
291 }
292
293 static uint32_t GetHashmapHashFromPort(Dart_Port port) {
294 return static_cast<uint32_t>(port & 0xFFFFFFFF);
295 }
296
297 static void* GetHashmapKeyFromPort(Dart_Port port) {
298 return reinterpret_cast<void*>(port);
299 }
300
301 public:
302 explicit DescriptorInfoMultiple(intptr_t fd)
303 : SI(fd), tokens_map_(&SamePortValue, 4) {}
304
305 virtual ~DescriptorInfoMultiple() {}
306
307 virtual bool IsListeningSocket() const { return true; }
308
309 virtual bool AddPort(Dart_Port port) {
310 HashMap::Entry* entry = tokens_map_.Lookup(
311 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), true);
312 entry->value = reinterpret_cast<void*>(kTokenCount);
313 return live_ports_.Add(port);
314 }
315
316 virtual bool RemovePort(Dart_Port port) {
317 HashMap::Entry* entry = tokens_map_.Lookup(
318 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false);
319 if (entry != NULL) {
320 intptr_t tokens = reinterpret_cast<intptr_t>(entry->value);
321 if (tokens == 0) {
322 while (idle_ports_.head() != port) {
323 idle_ports_.Rotate();
324 }
325 idle_ports_.RemoveHead();
326 } else {
327 while (live_ports_.head() != port) {
328 live_ports_.Rotate();
329 }
330 live_ports_.RemoveHead();
331 }
332 tokens_map_.Remove(
333 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port));
334 } else {
335 // NOTE: This is a listening socket which has been immediately closed.
336 //
337 // If a listening socket is not listened on, the event handler does not
338 // know about it beforehand. So the first time the event handler knows
339 // about it, is when it is supposed to be closed. We therefore do nothing
340 // here.
341 //
342 // But whether to close it, depends on whether other isolates have it open
343 // as well or not.
344 }
345 return !live_ports_.HasHead();
346 }
347
348 virtual Dart_Port NextPort() {
349 ASSERT(live_ports_.HasHead());
350 return live_ports_.head();
351 }
352
353 virtual bool HasNextPort() {
354 return live_ports_.HasHead();
355 }
356
357 virtual bool TakeToken() {
358 ASSERT(live_ports_.HasHead());
359 Dart_Port port = live_ports_.head();
360 HashMap::Entry* entry = tokens_map_.Lookup(
361 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false);
362 ASSERT(entry != NULL);
363 intptr_t tokens = reinterpret_cast<intptr_t>(entry->value);
364 tokens--;
365 entry->value = reinterpret_cast<void*>(tokens);
366 if (tokens == 0) {
367 live_ports_.RemoveHead();
368 idle_ports_.Add(port);
369 if (!live_ports_.HasHead()) {
370 return true;
371 }
372 } else {
373 live_ports_.Rotate();
374 }
375 return false;
376 }
377
378 virtual bool ReturnTokens(Dart_Port port, int count) {
379 HashMap::Entry* entry = tokens_map_.Lookup(
380 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false);
381 ASSERT(entry != NULL);
382 intptr_t tokens = reinterpret_cast<intptr_t>(entry->value);
383 tokens += count;
384 entry->value = reinterpret_cast<void*>(tokens);
385 if (tokens == count) {
386 // Return to live_ports_.
387 while (idle_ports_.head() != port) {
388 idle_ports_.Rotate();
389 }
390 idle_ports_.RemoveHead();
391 bool was_empty = !live_ports_.HasHead();
392 live_ports_.Add(port);
393 return was_empty;
394 }
395 return false;
396 }
397
398 virtual bool HasTokens() const {
399 return live_ports_.HasHead();
400 }
401
402 virtual void Close() {
403 SI::Close();
404 }
405
406 private:
407 CircularLinkedList<Dart_Port> live_ports_;
408 CircularLinkedList<Dart_Port> idle_ports_;
409 HashMap tokens_map_;
410 };
411
412
413 class InterruptMessage {
414 public:
415 intptr_t id;
416 Dart_Port dart_port;
417 int64_t data;
418 };
419
420
421 static const int kInterruptMessageSize = sizeof(InterruptMessage);
422 static const int kInfinityTimeout = -1;
423 static const int kTimerId = -1;
424 static const int kShutdownId = -2;
425
97 } // namespace bin 426 } // namespace bin
98 } // namespace dart 427 } // namespace dart
99 428
100 // The event handler delegation class is OS specific. 429 // The event handler delegation class is OS specific.
101 #if defined(TARGET_OS_ANDROID) 430 #if defined(TARGET_OS_ANDROID)
102 #include "bin/eventhandler_android.h" 431 #include "bin/eventhandler_android.h"
103 #elif defined(TARGET_OS_LINUX) 432 #elif defined(TARGET_OS_LINUX)
104 #include "bin/eventhandler_linux.h" 433 #include "bin/eventhandler_linux.h"
105 #elif defined(TARGET_OS_MACOS) 434 #elif defined(TARGET_OS_MACOS)
106 #include "bin/eventhandler_macos.h" 435 #include "bin/eventhandler_macos.h"
(...skipping 27 matching lines...) Expand all
134 463
135 private: 464 private:
136 friend class EventHandlerImplementation; 465 friend class EventHandlerImplementation;
137 EventHandlerImplementation delegate_; 466 EventHandlerImplementation delegate_;
138 }; 467 };
139 468
140 } // namespace bin 469 } // namespace bin
141 } // namespace dart 470 } // namespace dart
142 471
143 #endif // BIN_EVENTHANDLER_H_ 472 #endif // BIN_EVENTHANDLER_H_
OLDNEW
« no previous file with comments | « no previous file | dart/runtime/bin/eventhandler.cc » ('j') | dart/runtime/bin/eventhandler_android.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698