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 RUNTIME_BIN_EVENTHANDLER_H_ | 5 #ifndef RUNTIME_BIN_EVENTHANDLER_H_ |
6 #define RUNTIME_BIN_EVENTHANDLER_H_ | 6 #define RUNTIME_BIN_EVENTHANDLER_H_ |
7 | 7 |
8 #include "bin/builtin.h" | 8 #include "bin/builtin.h" |
9 #include "bin/dartutils.h" | 9 #include "bin/dartutils.h" |
10 #include "bin/isolate_data.h" | 10 #include "bin/isolate_data.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 kDestroyedEvent = 4, | 26 kDestroyedEvent = 4, |
27 kCloseCommand = 8, | 27 kCloseCommand = 8, |
28 kShutdownReadCommand = 9, | 28 kShutdownReadCommand = 9, |
29 kShutdownWriteCommand = 10, | 29 kShutdownWriteCommand = 10, |
30 kReturnTokenCommand = 11, | 30 kReturnTokenCommand = 11, |
31 kSetEventMaskCommand = 12, | 31 kSetEventMaskCommand = 12, |
32 kListeningSocket = 16, | 32 kListeningSocket = 16, |
33 kPipe = 17, | 33 kPipe = 17, |
34 }; | 34 }; |
35 | 35 |
36 #define COMMAND_MASK ((1 << kCloseCommand) | \ | 36 // clang-format off |
37 (1 << kShutdownReadCommand) | \ | 37 #define COMMAND_MASK ((1 << kCloseCommand) | \ |
38 (1 << kShutdownWriteCommand) | \ | 38 (1 << kShutdownReadCommand) | \ |
39 (1 << kReturnTokenCommand) | \ | 39 (1 << kShutdownWriteCommand) | \ |
| 40 (1 << kReturnTokenCommand) | \ |
40 (1 << kSetEventMaskCommand)) | 41 (1 << kSetEventMaskCommand)) |
41 #define EVENT_MASK ((1 << kInEvent) | \ | 42 #define EVENT_MASK ((1 << kInEvent) | \ |
42 (1 << kOutEvent) | \ | 43 (1 << kOutEvent) | \ |
43 (1 << kErrorEvent) | \ | 44 (1 << kErrorEvent) | \ |
44 (1 << kCloseEvent) | \ | 45 (1 << kCloseEvent) | \ |
45 (1 << kDestroyedEvent)) | 46 (1 << kDestroyedEvent)) |
46 #define IS_COMMAND(data, command_bit) \ | 47 #define IS_COMMAND(data, command_bit) \ |
47 ((data & COMMAND_MASK) == (1 << command_bit)) // NOLINT | 48 ((data & COMMAND_MASK) == (1 << command_bit)) // NOLINT |
48 #define IS_EVENT(data, event_bit) \ | 49 #define IS_EVENT(data, event_bit) \ |
49 ((data & EVENT_MASK) == (1 << event_bit)) // NOLINT | 50 ((data & EVENT_MASK) == (1 << event_bit)) // NOLINT |
50 #define IS_IO_EVENT(data) \ | 51 #define IS_IO_EVENT(data) \ |
51 ((data & (1 << kInEvent | 1 << kOutEvent | 1 << kCloseEvent)) != 0 && \ | 52 ((data & (1 << kInEvent | 1 << kOutEvent | 1 << kCloseEvent)) != 0 && \ |
52 (data & ~(1 << kInEvent | 1 << kOutEvent | 1 << kCloseEvent)) == 0) | 53 (data & ~(1 << kInEvent | 1 << kOutEvent | 1 << kCloseEvent)) == 0) |
53 #define IS_LISTENING_SOCKET(data) \ | 54 #define IS_LISTENING_SOCKET(data) \ |
54 ((data & (1 << kListeningSocket)) != 0) // NOLINT | 55 ((data & (1 << kListeningSocket)) != 0) // NOLINT |
55 #define TOKEN_COUNT(data) (data & ((1 << kCloseCommand) - 1)) | 56 #define TOKEN_COUNT(data) (data & ((1 << kCloseCommand) - 1)) |
| 57 // clang-format on |
56 | 58 |
57 class TimeoutQueue { | 59 class TimeoutQueue { |
58 private: | 60 private: |
59 class Timeout { | 61 class Timeout { |
60 public: | 62 public: |
61 Timeout(Dart_Port port, int64_t timeout, Timeout* next) | 63 Timeout(Dart_Port port, int64_t timeout, Timeout* next) |
62 : port_(port), timeout_(timeout), next_(next) {} | 64 : port_(port), timeout_(timeout), next_(next) {} |
63 | 65 |
64 Dart_Port port() const { return port_; } | 66 Dart_Port port() const { return port_; } |
65 | 67 |
66 int64_t timeout() const { return timeout_; } | 68 int64_t timeout() const { return timeout_; } |
67 void set_timeout(int64_t timeout) { | 69 void set_timeout(int64_t timeout) { |
68 ASSERT(timeout >= 0); | 70 ASSERT(timeout >= 0); |
69 timeout_ = timeout; | 71 timeout_ = timeout; |
70 } | 72 } |
71 | 73 |
72 Timeout* next() const { return next_; } | 74 Timeout* next() const { return next_; } |
73 void set_next(Timeout* next) { | 75 void set_next(Timeout* next) { next_ = next; } |
74 next_ = next; | |
75 } | |
76 | 76 |
77 private: | 77 private: |
78 Dart_Port port_; | 78 Dart_Port port_; |
79 int64_t timeout_; | 79 int64_t timeout_; |
80 Timeout* next_; | 80 Timeout* next_; |
81 }; | 81 }; |
82 | 82 |
83 public: | 83 public: |
84 TimeoutQueue() : next_timeout_(NULL), timeouts_(NULL) {} | 84 TimeoutQueue() : next_timeout_(NULL), timeouts_(NULL) {} |
85 | 85 |
86 ~TimeoutQueue() { | 86 ~TimeoutQueue() { |
87 while (HasTimeout()) RemoveCurrent(); | 87 while (HasTimeout()) |
| 88 RemoveCurrent(); |
88 } | 89 } |
89 | 90 |
90 bool HasTimeout() const { return next_timeout_ != NULL; } | 91 bool HasTimeout() const { return next_timeout_ != NULL; } |
91 | 92 |
92 int64_t CurrentTimeout() const { | 93 int64_t CurrentTimeout() const { |
93 ASSERT(next_timeout_ != NULL); | 94 ASSERT(next_timeout_ != NULL); |
94 return next_timeout_->timeout(); | 95 return next_timeout_->timeout(); |
95 } | 96 } |
96 | 97 |
97 Dart_Port CurrentPort() const { | 98 Dart_Port CurrentPort() const { |
98 ASSERT(next_timeout_ != NULL); | 99 ASSERT(next_timeout_ != NULL); |
99 return next_timeout_->port(); | 100 return next_timeout_->port(); |
100 } | 101 } |
101 | 102 |
102 void RemoveCurrent() { | 103 void RemoveCurrent() { UpdateTimeout(CurrentPort(), -1); } |
103 UpdateTimeout(CurrentPort(), -1); | |
104 } | |
105 | 104 |
106 void UpdateTimeout(Dart_Port port, int64_t timeout); | 105 void UpdateTimeout(Dart_Port port, int64_t timeout); |
107 | 106 |
108 private: | 107 private: |
109 Timeout* next_timeout_; | 108 Timeout* next_timeout_; |
110 Timeout* timeouts_; | 109 Timeout* timeouts_; |
111 | 110 |
112 DISALLOW_COPY_AND_ASSIGN(TimeoutQueue); | 111 DISALLOW_COPY_AND_ASSIGN(TimeoutQueue); |
113 }; | 112 }; |
114 | 113 |
115 | 114 |
116 class InterruptMessage { | 115 class InterruptMessage { |
117 public: | 116 public: |
118 intptr_t id; | 117 intptr_t id; |
119 Dart_Port dart_port; | 118 Dart_Port dart_port; |
120 int64_t data; | 119 int64_t data; |
121 }; | 120 }; |
122 | 121 |
123 | 122 |
124 static const int kInterruptMessageSize = sizeof(InterruptMessage); | 123 static const int kInterruptMessageSize = sizeof(InterruptMessage); |
125 static const int kInfinityTimeout = -1; | 124 static const int kInfinityTimeout = -1; |
126 static const int kTimerId = -1; | 125 static const int kTimerId = -1; |
127 static const int kShutdownId = -2; | 126 static const int kShutdownId = -2; |
128 | 127 |
129 | 128 |
130 template<typename T> | 129 template <typename T> |
131 class CircularLinkedList { | 130 class CircularLinkedList { |
132 public: | 131 public: |
133 CircularLinkedList() : head_(NULL) {} | 132 CircularLinkedList() : head_(NULL) {} |
134 | 133 |
135 typedef void (*ClearFun) (void* value); | 134 typedef void (*ClearFun)(void* value); |
136 | 135 |
137 // Returns true if the list was empty. | 136 // Returns true if the list was empty. |
138 bool Add(T t) { | 137 bool Add(T t) { |
139 Entry* e = new Entry(t); | 138 Entry* e = new Entry(t); |
140 if (head_ == NULL) { | 139 if (head_ == NULL) { |
141 // Empty list, make e head, and point to itself. | 140 // Empty list, make e head, and point to itself. |
142 e->next_ = e; | 141 e->next_ = e; |
143 e->prev_ = e; | 142 e->prev_ = e; |
144 head_ = e; | 143 head_ = e; |
145 return true; | 144 return true; |
(...skipping 27 matching lines...) Expand all Loading... |
173 void Remove(T item) { | 172 void Remove(T item) { |
174 if (head_ == NULL) { | 173 if (head_ == NULL) { |
175 return; | 174 return; |
176 } else if (head_ == head_->next_) { | 175 } else if (head_ == head_->next_) { |
177 if (head_->t == item) { | 176 if (head_->t == item) { |
178 delete head_; | 177 delete head_; |
179 head_ = NULL; | 178 head_ = NULL; |
180 return; | 179 return; |
181 } | 180 } |
182 } else { | 181 } else { |
183 Entry *current = head_; | 182 Entry* current = head_; |
184 do { | 183 do { |
185 if (current->t == item) { | 184 if (current->t == item) { |
186 Entry *next = current->next_; | 185 Entry* next = current->next_; |
187 Entry *prev = current->prev_; | 186 Entry* prev = current->prev_; |
188 prev->next_ = next; | 187 prev->next_ = next; |
189 next->prev_ = prev; | 188 next->prev_ = prev; |
190 | 189 |
191 if (current == head_) { | 190 if (current == head_) { |
192 head_ = head_->next_; | 191 head_ = head_->next_; |
193 } | 192 } |
194 | 193 |
195 delete current; | 194 delete current; |
196 return; | 195 return; |
197 } | 196 } |
198 current = current->next_; | 197 current = current->next_; |
199 } while (current != head_); | 198 } while (current != head_); |
200 } | 199 } |
201 } | 200 } |
202 | 201 |
203 void RemoveAll(ClearFun clear = NULL) { | 202 void RemoveAll(ClearFun clear = NULL) { |
204 while (HasHead()) { | 203 while (HasHead()) { |
205 RemoveHead(clear); | 204 RemoveHead(clear); |
206 } | 205 } |
207 } | 206 } |
208 | 207 |
209 T head() const { return head_->t; } | 208 T head() const { return head_->t; } |
210 | 209 |
211 bool HasHead() const { | 210 bool HasHead() const { return head_ != NULL; } |
212 return head_ != NULL; | |
213 } | |
214 | 211 |
215 void Rotate() { | 212 void Rotate() { |
216 if (head_ != NULL) { | 213 if (head_ != NULL) { |
217 ASSERT(head_->next_ != NULL); | 214 ASSERT(head_->next_ != NULL); |
218 head_ = head_->next_; | 215 head_ = head_->next_; |
219 } | 216 } |
220 } | 217 } |
221 | 218 |
222 private: | 219 private: |
223 struct Entry { | 220 struct Entry { |
224 explicit Entry(const T& t) : t(t), next_(NULL), prev_(NULL) {} | 221 explicit Entry(const T& t) : t(t), next_(NULL), prev_(NULL) {} |
225 const T t; | 222 const T t; |
226 Entry* next_; | 223 Entry* next_; |
227 Entry* prev_; | 224 Entry* prev_; |
228 }; | 225 }; |
229 | 226 |
230 Entry* head_; | 227 Entry* head_; |
231 | 228 |
232 DISALLOW_COPY_AND_ASSIGN(CircularLinkedList); | 229 DISALLOW_COPY_AND_ASSIGN(CircularLinkedList); |
233 }; | 230 }; |
234 | 231 |
235 | 232 |
236 class DescriptorInfoBase { | 233 class DescriptorInfoBase { |
237 public: | 234 public: |
238 explicit DescriptorInfoBase(intptr_t fd) : fd_(fd) { | 235 explicit DescriptorInfoBase(intptr_t fd) : fd_(fd) { ASSERT(fd_ != -1); } |
239 ASSERT(fd_ != -1); | |
240 } | |
241 | 236 |
242 virtual ~DescriptorInfoBase() {} | 237 virtual ~DescriptorInfoBase() {} |
243 | 238 |
244 // The OS descriptor. | 239 // The OS descriptor. |
245 intptr_t fd() { return fd_; } | 240 intptr_t fd() { return fd_; } |
246 | 241 |
247 // Whether this descriptor refers to an underlying listening OS socket. | 242 // Whether this descriptor refers to an underlying listening OS socket. |
248 virtual bool IsListeningSocket() const = 0; | 243 virtual bool IsListeningSocket() const = 0; |
249 | 244 |
250 // Inserts or updates a new Dart_Port which is interested in events specified | 245 // Inserts or updates a new Dart_Port which is interested in events specified |
(...skipping 29 matching lines...) Expand all Loading... |
280 | 275 |
281 private: | 276 private: |
282 DISALLOW_COPY_AND_ASSIGN(DescriptorInfoBase); | 277 DISALLOW_COPY_AND_ASSIGN(DescriptorInfoBase); |
283 }; | 278 }; |
284 | 279 |
285 | 280 |
286 // Describes a OS descriptor (e.g. file descriptor on linux or HANDLE on | 281 // Describes a OS descriptor (e.g. file descriptor on linux or HANDLE on |
287 // windows) which is connected to a single Dart_Port. | 282 // windows) which is connected to a single Dart_Port. |
288 // | 283 // |
289 // Subclasses of this class can be e.g. connected tcp sockets. | 284 // Subclasses of this class can be e.g. connected tcp sockets. |
290 template<typename DI> | 285 template <typename DI> |
291 class DescriptorInfoSingleMixin : public DI { | 286 class DescriptorInfoSingleMixin : public DI { |
292 private: | 287 private: |
293 static const int kTokenCount = 16; | 288 static const int kTokenCount = 16; |
294 | 289 |
295 public: | 290 public: |
296 DescriptorInfoSingleMixin(intptr_t fd, bool disable_tokens) | 291 DescriptorInfoSingleMixin(intptr_t fd, bool disable_tokens) |
297 : DI(fd), port_(0), tokens_(kTokenCount), mask_(0), | 292 : DI(fd), |
| 293 port_(0), |
| 294 tokens_(kTokenCount), |
| 295 mask_(0), |
298 disable_tokens_(disable_tokens) {} | 296 disable_tokens_(disable_tokens) {} |
299 | 297 |
300 virtual ~DescriptorInfoSingleMixin() { } | 298 virtual ~DescriptorInfoSingleMixin() {} |
301 | 299 |
302 virtual bool IsListeningSocket() const { return false; } | 300 virtual bool IsListeningSocket() const { return false; } |
303 | 301 |
304 virtual void SetPortAndMask(Dart_Port port, intptr_t mask) { | 302 virtual void SetPortAndMask(Dart_Port port, intptr_t mask) { |
305 ASSERT(port_ == 0 || port == port_); | 303 ASSERT(port_ == 0 || port == port_); |
306 port_ = port; | 304 port_ = port; |
307 mask_ = mask; | 305 mask_ = mask; |
308 } | 306 } |
309 | 307 |
310 virtual void RemovePort(Dart_Port port) { | 308 virtual void RemovePort(Dart_Port port) { |
(...skipping 14 matching lines...) Expand all Loading... |
325 IS_EVENT(events_ready, kDestroyedEvent)); | 323 IS_EVENT(events_ready, kDestroyedEvent)); |
326 if (!disable_tokens_) { | 324 if (!disable_tokens_) { |
327 tokens_--; | 325 tokens_--; |
328 } | 326 } |
329 return port_; | 327 return port_; |
330 } | 328 } |
331 | 329 |
332 virtual void NotifyAllDartPorts(uintptr_t events) { | 330 virtual void NotifyAllDartPorts(uintptr_t events) { |
333 // Unexpected close, asynchronous destroy or error events are the only | 331 // Unexpected close, asynchronous destroy or error events are the only |
334 // ones we broadcast to all listeners. | 332 // ones we broadcast to all listeners. |
335 ASSERT(IS_EVENT(events, kCloseEvent) || | 333 ASSERT(IS_EVENT(events, kCloseEvent) || IS_EVENT(events, kErrorEvent) || |
336 IS_EVENT(events, kErrorEvent) || | |
337 IS_EVENT(events, kDestroyedEvent)); | 334 IS_EVENT(events, kDestroyedEvent)); |
338 | 335 |
339 if (port_ != 0) { | 336 if (port_ != 0) { |
340 DartUtils::PostInt32(port_, events); | 337 DartUtils::PostInt32(port_, events); |
341 } | 338 } |
342 if (!disable_tokens_) { | 339 if (!disable_tokens_) { |
343 tokens_--; | 340 tokens_--; |
344 } | 341 } |
345 } | 342 } |
346 | 343 |
347 virtual void ReturnTokens(Dart_Port port, int count) { | 344 virtual void ReturnTokens(Dart_Port port, int count) { |
348 ASSERT(port_ == port); | 345 ASSERT(port_ == port); |
349 if (!disable_tokens_) { | 346 if (!disable_tokens_) { |
350 tokens_ += count; | 347 tokens_ += count; |
351 } | 348 } |
352 ASSERT(tokens_ <= kTokenCount); | 349 ASSERT(tokens_ <= kTokenCount); |
353 } | 350 } |
354 | 351 |
355 virtual intptr_t Mask() { | 352 virtual intptr_t Mask() { |
356 if (tokens_ <= 0) { | 353 if (tokens_ <= 0) { |
357 return 0; | 354 return 0; |
358 } | 355 } |
359 return mask_; | 356 return mask_; |
360 } | 357 } |
361 | 358 |
362 virtual void Close() { | 359 virtual void Close() { DI::Close(); } |
363 DI::Close(); | |
364 } | |
365 | 360 |
366 private: | 361 private: |
367 Dart_Port port_; | 362 Dart_Port port_; |
368 int tokens_; | 363 int tokens_; |
369 intptr_t mask_; | 364 intptr_t mask_; |
370 bool disable_tokens_; | 365 bool disable_tokens_; |
371 | 366 |
372 DISALLOW_COPY_AND_ASSIGN(DescriptorInfoSingleMixin); | 367 DISALLOW_COPY_AND_ASSIGN(DescriptorInfoSingleMixin); |
373 }; | 368 }; |
374 | 369 |
375 | 370 |
376 // Describes a OS descriptor (e.g. file descriptor on linux or HANDLE on | 371 // Describes a OS descriptor (e.g. file descriptor on linux or HANDLE on |
377 // windows) which is connected to multiple Dart_Port's. | 372 // windows) which is connected to multiple Dart_Port's. |
378 // | 373 // |
379 // Subclasses of this class can be e.g. a listening socket which multiple | 374 // Subclasses of this class can be e.g. a listening socket which multiple |
380 // isolates are listening on. | 375 // isolates are listening on. |
381 template<typename DI> | 376 template <typename DI> |
382 class DescriptorInfoMultipleMixin : public DI { | 377 class DescriptorInfoMultipleMixin : public DI { |
383 private: | 378 private: |
384 static const int kTokenCount = 4; | 379 static const int kTokenCount = 4; |
385 | 380 |
386 static bool SamePortValue(void* key1, void* key2) { | 381 static bool SamePortValue(void* key1, void* key2) { |
387 return reinterpret_cast<Dart_Port>(key1) == | 382 return reinterpret_cast<Dart_Port>(key1) == |
388 reinterpret_cast<Dart_Port>(key2); | 383 reinterpret_cast<Dart_Port>(key2); |
389 } | 384 } |
390 | 385 |
391 static uint32_t GetHashmapHashFromPort(Dart_Port port) { | 386 static uint32_t GetHashmapHashFromPort(Dart_Port port) { |
392 return static_cast<uint32_t>(port & 0xFFFFFFFF); | 387 return static_cast<uint32_t>(port & 0xFFFFFFFF); |
393 } | 388 } |
394 | 389 |
395 static void* GetHashmapKeyFromPort(Dart_Port port) { | 390 static void* GetHashmapKeyFromPort(Dart_Port port) { |
396 return reinterpret_cast<void*>(port); | 391 return reinterpret_cast<void*>(port); |
397 } | 392 } |
398 | 393 |
399 static bool IsReadingMask(intptr_t mask) { | 394 static bool IsReadingMask(intptr_t mask) { |
400 if (mask == (1 << kInEvent)) { | 395 if (mask == (1 << kInEvent)) { |
401 return true; | 396 return true; |
402 } else { | 397 } else { |
403 ASSERT(mask == 0); | 398 ASSERT(mask == 0); |
404 return false; | 399 return false; |
405 } | 400 } |
406 } | 401 } |
407 | 402 |
408 struct PortEntry { | 403 struct PortEntry { |
409 Dart_Port dart_port; | 404 Dart_Port dart_port; |
410 intptr_t is_reading; | 405 intptr_t is_reading; |
411 intptr_t token_count; | 406 intptr_t token_count; |
412 | 407 |
413 bool IsReady() { return token_count > 0 && is_reading; } | 408 bool IsReady() { return token_count > 0 && is_reading; } |
414 }; | 409 }; |
415 | 410 |
416 public: | 411 public: |
417 DescriptorInfoMultipleMixin(intptr_t fd, bool disable_tokens) | 412 DescriptorInfoMultipleMixin(intptr_t fd, bool disable_tokens) |
418 : DI(fd), tokens_map_(&SamePortValue, kTokenCount), | 413 : DI(fd), |
| 414 tokens_map_(&SamePortValue, kTokenCount), |
419 disable_tokens_(disable_tokens) {} | 415 disable_tokens_(disable_tokens) {} |
420 | 416 |
421 virtual ~DescriptorInfoMultipleMixin() { | 417 virtual ~DescriptorInfoMultipleMixin() { RemoveAllPorts(); } |
422 RemoveAllPorts(); | |
423 } | |
424 | 418 |
425 virtual bool IsListeningSocket() const { return true; } | 419 virtual bool IsListeningSocket() const { return true; } |
426 | 420 |
427 virtual void SetPortAndMask(Dart_Port port, intptr_t mask) { | 421 virtual void SetPortAndMask(Dart_Port port, intptr_t mask) { |
428 HashMap::Entry* entry = tokens_map_.Lookup( | 422 HashMap::Entry* entry = tokens_map_.Lookup( |
429 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), true); | 423 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), true); |
430 PortEntry* pentry; | 424 PortEntry* pentry; |
431 if (entry->value == NULL) { | 425 if (entry->value == NULL) { |
432 pentry = new PortEntry(); | 426 pentry = new PortEntry(); |
433 pentry->dart_port = port; | 427 pentry->dart_port = port; |
(...skipping 25 matching lines...) Expand all Loading... |
459 PortEntry* root = reinterpret_cast<PortEntry*>(active_readers_.head()); | 453 PortEntry* root = reinterpret_cast<PortEntry*>(active_readers_.head()); |
460 PortEntry* current = root; | 454 PortEntry* current = root; |
461 do { | 455 do { |
462 ASSERT(current->IsReady()); | 456 ASSERT(current->IsReady()); |
463 ready_count++; | 457 ready_count++; |
464 active_readers_.Rotate(); | 458 active_readers_.Rotate(); |
465 current = active_readers_.head(); | 459 current = active_readers_.head(); |
466 } while (current != root); | 460 } while (current != root); |
467 } | 461 } |
468 | 462 |
469 for (HashMap::Entry *entry = tokens_map_.Start(); | 463 for (HashMap::Entry* entry = tokens_map_.Start(); entry != NULL; |
470 entry != NULL; | |
471 entry = tokens_map_.Next(entry)) { | 464 entry = tokens_map_.Next(entry)) { |
472 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); | 465 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); |
473 if (pentry->IsReady()) { | 466 if (pentry->IsReady()) { |
474 ready_count--; | 467 ready_count--; |
475 } | 468 } |
476 } | 469 } |
477 // Ensure all ready items are in `active_readers_`. | 470 // Ensure all ready items are in `active_readers_`. |
478 ASSERT(ready_count == 0); | 471 ASSERT(ready_count == 0); |
479 #endif | 472 #endif |
480 } | 473 } |
481 | 474 |
482 virtual void RemovePort(Dart_Port port) { | 475 virtual void RemovePort(Dart_Port port) { |
483 HashMap::Entry* entry = tokens_map_.Lookup( | 476 HashMap::Entry* entry = tokens_map_.Lookup( |
484 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false); | 477 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false); |
485 if (entry != NULL) { | 478 if (entry != NULL) { |
486 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); | 479 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); |
487 if (pentry->IsReady()) { | 480 if (pentry->IsReady()) { |
488 active_readers_.Remove(pentry); | 481 active_readers_.Remove(pentry); |
489 } | 482 } |
490 tokens_map_.Remove( | 483 tokens_map_.Remove(GetHashmapKeyFromPort(port), |
491 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port)); | 484 GetHashmapHashFromPort(port)); |
492 delete pentry; | 485 delete pentry; |
493 } else { | 486 } else { |
494 // NOTE: This is a listening socket which has been immediately closed. | 487 // NOTE: This is a listening socket which has been immediately closed. |
495 // | 488 // |
496 // If a listening socket is not listened on, the event handler does not | 489 // If a listening socket is not listened on, the event handler does not |
497 // know about it beforehand. So the first time the event handler knows | 490 // know about it beforehand. So the first time the event handler knows |
498 // about it, is when it is supposed to be closed. We therefore do nothing | 491 // about it, is when it is supposed to be closed. We therefore do nothing |
499 // here. | 492 // here. |
500 // | 493 // |
501 // But whether to close it, depends on whether other isolates have it open | 494 // But whether to close it, depends on whether other isolates have it open |
502 // as well or not. | 495 // as well or not. |
503 } | 496 } |
504 } | 497 } |
505 | 498 |
506 virtual void RemoveAllPorts() { | 499 virtual void RemoveAllPorts() { |
507 for (HashMap::Entry *entry = tokens_map_.Start(); | 500 for (HashMap::Entry* entry = tokens_map_.Start(); entry != NULL; |
508 entry != NULL; | |
509 entry = tokens_map_.Next(entry)) { | 501 entry = tokens_map_.Next(entry)) { |
510 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); | 502 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); |
511 entry->value = NULL; | 503 entry->value = NULL; |
512 active_readers_.Remove(pentry); | 504 active_readers_.Remove(pentry); |
513 delete pentry; | 505 delete pentry; |
514 } | 506 } |
515 tokens_map_.Clear(); | 507 tokens_map_.Clear(); |
516 active_readers_.RemoveAll(DeletePortEntry); | 508 active_readers_.RemoveAll(DeletePortEntry); |
517 } | 509 } |
518 | 510 |
(...skipping 17 matching lines...) Expand all Loading... |
536 } | 528 } |
537 | 529 |
538 return pentry->dart_port; | 530 return pentry->dart_port; |
539 } | 531 } |
540 return 0; | 532 return 0; |
541 } | 533 } |
542 | 534 |
543 virtual void NotifyAllDartPorts(uintptr_t events) { | 535 virtual void NotifyAllDartPorts(uintptr_t events) { |
544 // Unexpected close, asynchronous destroy or error events are the only | 536 // Unexpected close, asynchronous destroy or error events are the only |
545 // ones we broadcast to all listeners. | 537 // ones we broadcast to all listeners. |
546 ASSERT(IS_EVENT(events, kCloseEvent) || | 538 ASSERT(IS_EVENT(events, kCloseEvent) || IS_EVENT(events, kErrorEvent) || |
547 IS_EVENT(events, kErrorEvent) || | |
548 IS_EVENT(events, kDestroyedEvent)); | 539 IS_EVENT(events, kDestroyedEvent)); |
549 | 540 |
550 for (HashMap::Entry *entry = tokens_map_.Start(); | 541 for (HashMap::Entry* entry = tokens_map_.Start(); entry != NULL; |
551 entry != NULL; | |
552 entry = tokens_map_.Next(entry)) { | 542 entry = tokens_map_.Next(entry)) { |
553 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); | 543 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); |
554 DartUtils::PostInt32(pentry->dart_port, events); | 544 DartUtils::PostInt32(pentry->dart_port, events); |
555 | 545 |
556 // Update token count. | 546 // Update token count. |
557 bool was_ready = pentry->IsReady(); | 547 bool was_ready = pentry->IsReady(); |
558 if (!disable_tokens_) { | 548 if (!disable_tokens_) { |
559 pentry->token_count--; | 549 pentry->token_count--; |
560 } | 550 } |
561 | 551 |
(...skipping 20 matching lines...) Expand all Loading... |
582 } | 572 } |
583 } | 573 } |
584 | 574 |
585 virtual intptr_t Mask() { | 575 virtual intptr_t Mask() { |
586 if (active_readers_.HasHead()) { | 576 if (active_readers_.HasHead()) { |
587 return 1 << kInEvent; | 577 return 1 << kInEvent; |
588 } | 578 } |
589 return 0; | 579 return 0; |
590 } | 580 } |
591 | 581 |
592 virtual void Close() { | 582 virtual void Close() { DI::Close(); } |
593 DI::Close(); | |
594 } | |
595 | 583 |
596 private: | 584 private: |
597 static void DeletePortEntry(void* data) { | 585 static void DeletePortEntry(void* data) { |
598 PortEntry* entry = reinterpret_cast<PortEntry*>(data); | 586 PortEntry* entry = reinterpret_cast<PortEntry*>(data); |
599 delete entry; | 587 delete entry; |
600 } | 588 } |
601 | 589 |
602 // The [Dart_Port]s which are not paused (i.e. are interested in read events, | 590 // The [Dart_Port]s which are not paused (i.e. are interested in read events, |
603 // i.e. `mask == (1 << kInEvent)`) and we have enough tokens to communicate | 591 // i.e. `mask == (1 << kInEvent)`) and we have enough tokens to communicate |
604 // with them. | 592 // with them. |
605 CircularLinkedList<PortEntry *> active_readers_; | 593 CircularLinkedList<PortEntry*> active_readers_; |
606 | 594 |
607 // A convenience mapping: | 595 // A convenience mapping: |
608 // Dart_Port -> struct PortEntry { dart_port, mask, token_count } | 596 // Dart_Port -> struct PortEntry { dart_port, mask, token_count } |
609 HashMap tokens_map_; | 597 HashMap tokens_map_; |
610 | 598 |
611 bool disable_tokens_; | 599 bool disable_tokens_; |
612 | 600 |
613 DISALLOW_COPY_AND_ASSIGN(DescriptorInfoMultipleMixin); | 601 DISALLOW_COPY_AND_ASSIGN(DescriptorInfoMultipleMixin); |
614 }; | 602 }; |
615 | 603 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 friend class EventHandlerImplementation; | 651 friend class EventHandlerImplementation; |
664 EventHandlerImplementation delegate_; | 652 EventHandlerImplementation delegate_; |
665 | 653 |
666 DISALLOW_COPY_AND_ASSIGN(EventHandler); | 654 DISALLOW_COPY_AND_ASSIGN(EventHandler); |
667 }; | 655 }; |
668 | 656 |
669 } // namespace bin | 657 } // namespace bin |
670 } // namespace dart | 658 } // namespace dart |
671 | 659 |
672 #endif // RUNTIME_BIN_EVENTHANDLER_H_ | 660 #endif // RUNTIME_BIN_EVENTHANDLER_H_ |
OLD | NEW |