| 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 { |
| 145 // Insert e as the last element in the list. | 147 // Insert e as the last element in the list. |
| 146 e->prev_ = head_->prev_; | 148 e->prev_ = head_->prev_; |
| 147 e->next_ = head_; | 149 e->next_ = head_; |
| 148 e->prev_->next_ = e; | 150 e->prev_->next_ = e; |
| 149 head_->prev_ = e; | 151 head_->prev_ = e; |
| 150 return false; | 152 return false; |
| 151 } | 153 } |
| 152 } | 154 } |
| 153 | 155 |
| 154 void RemoveHead() { | 156 void RemoveHead(ClearFun clear = NULL) { |
| 155 ASSERT(head_ != NULL); | 157 ASSERT(head_ != NULL); |
| 156 | 158 |
| 157 Entry* e = head_; | 159 Entry* e = head_; |
| 158 if (e->next_ == e) { | 160 if (e->next_ == e) { |
| 159 head_ = NULL; | 161 head_ = NULL; |
| 160 } else { | 162 } else { |
| 161 e->prev_->next_ = e->next_; | 163 e->prev_->next_ = e->next_; |
| 162 e->next_->prev_ = e->prev_; | 164 e->next_->prev_ = e->prev_; |
| 163 head_ = e->next_; | 165 head_ = e->next_; |
| 164 } | 166 } |
| 167 if (clear != NULL) { |
| 168 clear(reinterpret_cast<void*>(e->t)); |
| 169 } |
| 165 delete e; | 170 delete e; |
| 166 } | 171 } |
| 167 | 172 |
| 168 void Remove(T item) { | 173 void Remove(T item) { |
| 169 if (head_ == NULL) { | 174 if (head_ == NULL) { |
| 170 return; | 175 return; |
| 171 } else if (head_ == head_->next_) { | 176 } else if (head_ == head_->next_) { |
| 172 if (head_->t == item) { | 177 if (head_->t == item) { |
| 173 delete head_; | 178 delete head_; |
| 174 head_ = NULL; | 179 head_ = NULL; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 188 } | 193 } |
| 189 | 194 |
| 190 delete current; | 195 delete current; |
| 191 return; | 196 return; |
| 192 } | 197 } |
| 193 current = current->next_; | 198 current = current->next_; |
| 194 } while (current != head_); | 199 } while (current != head_); |
| 195 } | 200 } |
| 196 } | 201 } |
| 197 | 202 |
| 198 void RemoveAll() { | 203 void RemoveAll(ClearFun clear = NULL) { |
| 199 while (HasHead()) { | 204 while (HasHead()) { |
| 200 RemoveHead(); | 205 RemoveHead(clear); |
| 201 } | 206 } |
| 202 } | 207 } |
| 203 | 208 |
| 204 T head() const { return head_->t; } | 209 T head() const { return head_->t; } |
| 205 | 210 |
| 206 bool HasHead() const { | 211 bool HasHead() const { |
| 207 return head_ != NULL; | 212 return head_ != NULL; |
| 208 } | 213 } |
| 209 | 214 |
| 210 void Rotate() { | 215 void Rotate() { |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 intptr_t token_count; | 411 intptr_t token_count; |
| 407 | 412 |
| 408 bool IsReady() { return token_count > 0 && is_reading; } | 413 bool IsReady() { return token_count > 0 && is_reading; } |
| 409 }; | 414 }; |
| 410 | 415 |
| 411 public: | 416 public: |
| 412 DescriptorInfoMultipleMixin(intptr_t fd, bool disable_tokens) | 417 DescriptorInfoMultipleMixin(intptr_t fd, bool disable_tokens) |
| 413 : DI(fd), tokens_map_(&SamePortValue, kTokenCount), | 418 : DI(fd), tokens_map_(&SamePortValue, kTokenCount), |
| 414 disable_tokens_(disable_tokens) {} | 419 disable_tokens_(disable_tokens) {} |
| 415 | 420 |
| 416 virtual ~DescriptorInfoMultipleMixin() {} | 421 virtual ~DescriptorInfoMultipleMixin() { |
| 422 RemoveAllPorts(); |
| 423 } |
| 417 | 424 |
| 418 virtual bool IsListeningSocket() const { return true; } | 425 virtual bool IsListeningSocket() const { return true; } |
| 419 | 426 |
| 420 virtual void SetPortAndMask(Dart_Port port, intptr_t mask) { | 427 virtual void SetPortAndMask(Dart_Port port, intptr_t mask) { |
| 421 HashMap::Entry* entry = tokens_map_.Lookup( | 428 HashMap::Entry* entry = tokens_map_.Lookup( |
| 422 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), true); | 429 GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), true); |
| 423 PortEntry* pentry; | 430 PortEntry* pentry; |
| 424 if (entry->value == NULL) { | 431 if (entry->value == NULL) { |
| 425 pentry = new PortEntry(); | 432 pentry = new PortEntry(); |
| 426 pentry->dart_port = port; | 433 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 | 497 // 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 | 498 // about it, is when it is supposed to be closed. We therefore do nothing |
| 492 // here. | 499 // here. |
| 493 // | 500 // |
| 494 // But whether to close it, depends on whether other isolates have it open | 501 // But whether to close it, depends on whether other isolates have it open |
| 495 // as well or not. | 502 // as well or not. |
| 496 } | 503 } |
| 497 } | 504 } |
| 498 | 505 |
| 499 virtual void RemoveAllPorts() { | 506 virtual void RemoveAllPorts() { |
| 500 active_readers_.RemoveAll(); | |
| 501 for (HashMap::Entry *entry = tokens_map_.Start(); | 507 for (HashMap::Entry *entry = tokens_map_.Start(); |
| 502 entry != NULL; | 508 entry != NULL; |
| 503 entry = tokens_map_.Next(entry)) { | 509 entry = tokens_map_.Next(entry)) { |
| 504 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); | 510 PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value); |
| 511 entry->value = NULL; |
| 512 active_readers_.Remove(pentry); |
| 505 delete pentry; | 513 delete pentry; |
| 506 } | 514 } |
| 507 tokens_map_.Clear(); | 515 tokens_map_.Clear(); |
| 516 active_readers_.RemoveAll(DeletePortEntry); |
| 508 } | 517 } |
| 509 | 518 |
| 510 virtual Dart_Port NextNotifyDartPort(intptr_t events_ready) { | 519 virtual Dart_Port NextNotifyDartPort(intptr_t events_ready) { |
| 511 // We're only sending `kInEvents` if there are multiple listeners (which is | 520 // We're only sending `kInEvents` if there are multiple listeners (which is |
| 512 // listening socktes). | 521 // listening socktes). |
| 513 ASSERT(IS_EVENT(events_ready, kInEvent) || | 522 ASSERT(IS_EVENT(events_ready, kInEvent) || |
| 514 IS_EVENT(events_ready, kDestroyedEvent)); | 523 IS_EVENT(events_ready, kDestroyedEvent)); |
| 515 | 524 |
| 516 if (active_readers_.HasHead()) { | 525 if (active_readers_.HasHead()) { |
| 517 PortEntry* pentry = reinterpret_cast<PortEntry*>(active_readers_.head()); | 526 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; | 587 return 1 << kInEvent; |
| 579 } | 588 } |
| 580 return 0; | 589 return 0; |
| 581 } | 590 } |
| 582 | 591 |
| 583 virtual void Close() { | 592 virtual void Close() { |
| 584 DI::Close(); | 593 DI::Close(); |
| 585 } | 594 } |
| 586 | 595 |
| 587 private: | 596 private: |
| 597 static void DeletePortEntry(void* data) { |
| 598 PortEntry* entry = reinterpret_cast<PortEntry*>(data); |
| 599 delete entry; |
| 600 } |
| 601 |
| 588 // The [Dart_Port]s which are not paused (i.e. are interested in read events, | 602 // 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 | 603 // i.e. `mask == (1 << kInEvent)`) and we have enough tokens to communicate |
| 590 // with them. | 604 // with them. |
| 591 CircularLinkedList<PortEntry *> active_readers_; | 605 CircularLinkedList<PortEntry *> active_readers_; |
| 592 | 606 |
| 593 // A convenience mapping: | 607 // A convenience mapping: |
| 594 // Dart_Port -> struct PortEntry { dart_port, mask, token_count } | 608 // Dart_Port -> struct PortEntry { dart_port, mask, token_count } |
| 595 HashMap tokens_map_; | 609 HashMap tokens_map_; |
| 596 | 610 |
| 597 bool disable_tokens_; | 611 bool disable_tokens_; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 friend class EventHandlerImplementation; | 663 friend class EventHandlerImplementation; |
| 650 EventHandlerImplementation delegate_; | 664 EventHandlerImplementation delegate_; |
| 651 | 665 |
| 652 DISALLOW_COPY_AND_ASSIGN(EventHandler); | 666 DISALLOW_COPY_AND_ASSIGN(EventHandler); |
| 653 }; | 667 }; |
| 654 | 668 |
| 655 } // namespace bin | 669 } // namespace bin |
| 656 } // namespace dart | 670 } // namespace dart |
| 657 | 671 |
| 658 #endif // BIN_EVENTHANDLER_H_ | 672 #endif // BIN_EVENTHANDLER_H_ |
| OLD | NEW |