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 |