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_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/dartutils.h" | 9 #include "bin/dartutils.h" |
10 #include "bin/isolate_data.h" | 10 #include "bin/isolate_data.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
125 static const int kInfinityTimeout = -1; | 125 static const int kInfinityTimeout = -1; |
126 static const int kTimerId = -1; | 126 static const int kTimerId = -1; |
127 static const int kShutdownId = -2; | 127 static const int kShutdownId = -2; |
128 | 128 |
129 | 129 |
130 template<typename T> | 130 template<typename T> |
131 class CircularLinkedList { | 131 class CircularLinkedList { |
132 public: | 132 public: |
133 CircularLinkedList() : head_(NULL) {} | 133 CircularLinkedList() : head_(NULL) {} |
134 | 134 |
135 typedef void (*ClearFun) (void* value); | |
136 | |
135 // Returns true if the list was empty. | 137 // Returns true if the list was empty. |
136 bool Add(T t) { | 138 bool Add(T t) { |
137 Entry* e = new Entry(t); | 139 Entry* e = new Entry(t); |
138 if (head_ == NULL) { | 140 if (head_ == NULL) { |
139 // Empty list, make e head, and point to itself. | 141 // Empty list, make e head, and point to itself. |
140 e->next_ = e; | 142 e->next_ = e; |
141 e->prev_ = e; | 143 e->prev_ = e; |
142 head_ = e; | 144 head_ = e; |
143 return true; | 145 return true; |
144 } else { | 146 } else { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 } | 190 } |
189 | 191 |
190 delete current; | 192 delete current; |
191 return; | 193 return; |
192 } | 194 } |
193 current = current->next_; | 195 current = current->next_; |
194 } while (current != head_); | 196 } while (current != head_); |
195 } | 197 } |
196 } | 198 } |
197 | 199 |
198 void RemoveAll() { | 200 void RemoveAll(ClearFun clear = NULL) { |
199 while (HasHead()) { | 201 while (HasHead()) { |
202 if (clear != NULL) { | |
203 T h = head(); | |
204 clear(reinterpret_cast<void*>(h)); | |
205 } | |
200 RemoveHead(); | 206 RemoveHead(); |
siva
2016/08/09 21:41:43
Wouldn't it be more atomic to pass the clear funct
zra
2016/08/09 22:19:27
Done. The DescriptorInfos and therefore the Circul
| |
201 } | 207 } |
202 } | 208 } |
203 | 209 |
204 T head() const { return head_->t; } | 210 T head() const { return head_->t; } |
205 | 211 |
206 bool HasHead() const { | 212 bool HasHead() const { |
207 return head_ != NULL; | 213 return head_ != NULL; |
208 } | 214 } |
209 | 215 |
210 void Rotate() { | 216 void Rotate() { |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
406 intptr_t token_count; | 412 intptr_t token_count; |
407 | 413 |
408 bool IsReady() { return token_count > 0 && is_reading; } | 414 bool IsReady() { return token_count > 0 && is_reading; } |
409 }; | 415 }; |
410 | 416 |
411 public: | 417 public: |
412 DescriptorInfoMultipleMixin(intptr_t fd, bool disable_tokens) | 418 DescriptorInfoMultipleMixin(intptr_t fd, bool disable_tokens) |
413 : DI(fd), tokens_map_(&SamePortValue, kTokenCount), | 419 : DI(fd), tokens_map_(&SamePortValue, kTokenCount), |
414 disable_tokens_(disable_tokens) {} | 420 disable_tokens_(disable_tokens) {} |
415 | 421 |
416 virtual ~DescriptorInfoMultipleMixin() {} | 422 virtual ~DescriptorInfoMultipleMixin() { |
423 RemoveAllPorts(); | |
424 } | |
417 | 425 |
418 virtual bool IsListeningSocket() const { return true; } | 426 virtual bool IsListeningSocket() const { return true; } |
419 | 427 |
420 virtual void SetPortAndMask(Dart_Port port, intptr_t mask) { | 428 virtual void SetPortAndMask(Dart_Port port, intptr_t mask) { |
421 HashMap::Entry* entry = tokens_map_.Lookup( | 429 HashMap::Entry* entry = tokens_map_.Lookup( |
422 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), true); | 430 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), true); |
423 PortEntry* pentry; | 431 PortEntry* pentry; |
424 if (entry->value == NULL) { | 432 if (entry->value == NULL) { |
425 pentry = new PortEntry(); | 433 pentry = new PortEntry(); |
426 pentry->dart_port = port; | 434 pentry->dart_port = port; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 // know about it beforehand. So the first time the event handler knows | 498 // know about it beforehand. So the first time the event handler knows |
491 // about it, is when it is supposed to be closed. We therefore do nothing | 499 // about it, is when it is supposed to be closed. We therefore do nothing |
492 // here. | 500 // here. |
493 // | 501 // |
494 // But whether to close it, depends on whether other isolates have it open | 502 // But whether to close it, depends on whether other isolates have it open |
495 // as well or not. | 503 // as well or not. |
496 } | 504 } |
497 } | 505 } |
498 | 506 |
499 virtual void RemoveAllPorts() { | 507 virtual void RemoveAllPorts() { |
500 active_readers_.RemoveAll(); | |
501 for (HashMap::Entry *entry = tokens_map_.Start(); | 508 for (HashMap::Entry *entry = tokens_map_.Start(); |
502 entry != NULL; | 509 entry != NULL; |
503 entry = tokens_map_.Next(entry)) { | 510 entry = tokens_map_.Next(entry)) { |
504 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); | 511 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); |
512 entry->value = NULL; | |
513 active_readers_.Remove(pentry); | |
505 delete pentry; | 514 delete pentry; |
506 } | 515 } |
507 tokens_map_.Clear(); | 516 tokens_map_.Clear(); |
517 active_readers_.RemoveAll(DeletePortEntry); | |
508 } | 518 } |
509 | 519 |
510 virtual Dart_Port NextNotifyDartPort(intptr_t events_ready) { | 520 virtual Dart_Port NextNotifyDartPort(intptr_t events_ready) { |
511 // We're only sending `kInEvents` if there are multiple listeners (which is | 521 // We're only sending `kInEvents` if there are multiple listeners (which is |
512 // listening socktes). | 522 // listening socktes). |
513 ASSERT(IS_EVENT(events_ready, kInEvent) || | 523 ASSERT(IS_EVENT(events_ready, kInEvent) || |
514 IS_EVENT(events_ready, kDestroyedEvent)); | 524 IS_EVENT(events_ready, kDestroyedEvent)); |
515 | 525 |
516 if (active_readers_.HasHead()) { | 526 if (active_readers_.HasHead()) { |
517 PortEntry* pentry = reinterpret_cast<PortEntry*>(active_readers_.head()); | 527 PortEntry* pentry = reinterpret_cast<PortEntry*>(active_readers_.head()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
578 return 1 << kInEvent; | 588 return 1 << kInEvent; |
579 } | 589 } |
580 return 0; | 590 return 0; |
581 } | 591 } |
582 | 592 |
583 virtual void Close() { | 593 virtual void Close() { |
584 DI::Close(); | 594 DI::Close(); |
585 } | 595 } |
586 | 596 |
587 private: | 597 private: |
598 static void DeletePortEntry(void* data) { | |
599 PortEntry* entry = reinterpret_cast<PortEntry*>(data); | |
600 delete entry; | |
601 } | |
602 | |
588 // The [Dart_Port]s which are not paused (i.e. are interested in read events, | 603 // The [Dart_Port]s which are not paused (i.e. are interested in read events, |
589 // i.e. `mask == (1 << kInEvent)`) and we have enough tokens to communicate | 604 // i.e. `mask == (1 << kInEvent)`) and we have enough tokens to communicate |
590 // with them. | 605 // with them. |
591 CircularLinkedList<PortEntry *> active_readers_; | 606 CircularLinkedList<PortEntry *> active_readers_; |
592 | 607 |
593 // A convenience mapping: | 608 // A convenience mapping: |
594 // Dart_Port -> struct PortEntry { dart_port, mask, token_count } | 609 // Dart_Port -> struct PortEntry { dart_port, mask, token_count } |
595 HashMap tokens_map_; | 610 HashMap tokens_map_; |
596 | 611 |
597 bool disable_tokens_; | 612 bool disable_tokens_; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
649 friend class EventHandlerImplementation; | 664 friend class EventHandlerImplementation; |
650 EventHandlerImplementation delegate_; | 665 EventHandlerImplementation delegate_; |
651 | 666 |
652 DISALLOW_COPY_AND_ASSIGN(EventHandler); | 667 DISALLOW_COPY_AND_ASSIGN(EventHandler); |
653 }; | 668 }; |
654 | 669 |
655 } // namespace bin | 670 } // namespace bin |
656 } // namespace dart | 671 } // namespace dart |
657 | 672 |
658 #endif // BIN_EVENTHANDLER_H_ | 673 #endif // BIN_EVENTHANDLER_H_ |
OLD | NEW |