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