| 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 |