| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 #include "vm/message_queue.h" | |
| 6 | |
| 7 namespace dart { | |
| 8 | |
| 9 MessageQueue::MessageQueue() { | |
| 10 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | |
| 11 head_[p] = NULL; | |
| 12 tail_[p] = NULL; | |
| 13 } | |
| 14 } | |
| 15 | |
| 16 | |
| 17 MessageQueue::~MessageQueue() { | |
| 18 // Ensure that all pending messages have been released. | |
| 19 #if defined(DEBUG) | |
| 20 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | |
| 21 ASSERT(head_[p] == NULL); | |
| 22 } | |
| 23 #endif | |
| 24 } | |
| 25 | |
| 26 | |
| 27 void MessageQueue::Enqueue(Message* msg) { | |
| 28 // TODO(turnidge): Add a scoped locker for monitors which is not a | |
| 29 // stack resource. This would probably be useful in the platform | |
| 30 // headers. | |
| 31 monitor_.Enter(); | |
| 32 | |
| 33 Message::Priority p = msg->priority(); | |
| 34 // Make sure messages are not reused. | |
| 35 ASSERT(msg->next_ == NULL); | |
| 36 if (head_[p] == NULL) { | |
| 37 // Only element in the queue. | |
| 38 head_[p] = msg; | |
| 39 tail_[p] = msg; | |
| 40 | |
| 41 // We only need to notify if the queue was empty. | |
| 42 monitor_.Notify(); | |
| 43 } else { | |
| 44 ASSERT(tail_[p] != NULL); | |
| 45 // Append at the tail. | |
| 46 tail_[p]->next_ = msg; | |
| 47 tail_[p] = msg; | |
| 48 } | |
| 49 | |
| 50 monitor_.Exit(); | |
| 51 } | |
| 52 | |
| 53 Message* MessageQueue::DequeueNoWait() { | |
| 54 MonitorLocker ml(&monitor_); | |
| 55 return DequeueNoWaitHoldsLock(); | |
| 56 } | |
| 57 | |
| 58 Message* MessageQueue::DequeueNoWaitHoldsLock() { | |
| 59 // Look for the highest priority available message. | |
| 60 for (int p = Message::kNumPriorities-1; p >= Message::kFirstPriority; p--) { | |
| 61 Message* result = head_[p]; | |
| 62 if (result != NULL) { | |
| 63 head_[p] = result->next_; | |
| 64 // The following update to tail_ is not strictly needed. | |
| 65 if (head_[p] == NULL) { | |
| 66 tail_[p] = NULL; | |
| 67 } | |
| 68 #if defined(DEBUG) | |
| 69 result->next_ = result; // Make sure to trigger ASSERT in Enqueue. | |
| 70 #endif // DEBUG | |
| 71 return result; | |
| 72 } | |
| 73 } | |
| 74 return NULL; | |
| 75 } | |
| 76 | |
| 77 | |
| 78 Message* MessageQueue::Dequeue(int64_t millis) { | |
| 79 ASSERT(millis >= 0); | |
| 80 MonitorLocker ml(&monitor_); | |
| 81 | |
| 82 Message* result = DequeueNoWaitHoldsLock(); | |
| 83 if (result == NULL) { | |
| 84 // No message available at any priority. | |
| 85 ml.Wait(millis); | |
| 86 result = DequeueNoWaitHoldsLock(); | |
| 87 } | |
| 88 return result; | |
| 89 } | |
| 90 | |
| 91 | |
| 92 void MessageQueue::Flush(Dart_Port port) { | |
| 93 MonitorLocker ml(&monitor_); | |
| 94 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | |
| 95 Message* cur = head_[p]; | |
| 96 Message* prev = NULL; | |
| 97 while (cur != NULL) { | |
| 98 Message* next = cur->next_; | |
| 99 // If the message matches, then remove it from the queue and delete it. | |
| 100 if (cur->dest_port() == port) { | |
| 101 if (prev != NULL) { | |
| 102 prev->next_ = next; | |
| 103 } else { | |
| 104 head_[p] = next; | |
| 105 } | |
| 106 delete cur; | |
| 107 } else { | |
| 108 // Move prev forward. | |
| 109 prev = cur; | |
| 110 } | |
| 111 // Advance to the next message in the queue. | |
| 112 cur = next; | |
| 113 } | |
| 114 tail_[p] = prev; | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 | |
| 119 void MessageQueue::FlushAll() { | |
| 120 MonitorLocker ml(&monitor_); | |
| 121 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | |
| 122 Message* cur = head_[p]; | |
| 123 head_[p] = NULL; | |
| 124 tail_[p] = NULL; | |
| 125 while (cur != NULL) { | |
| 126 Message* next = cur->next_; | |
| 127 delete cur; | |
| 128 cur = next; | |
| 129 } | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 | |
| 134 } // namespace dart | |
| OLD | NEW |