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.h" | 5 #include "vm/message.h" |
6 | 6 |
7 namespace dart { | 7 namespace dart { |
8 | 8 |
9 DECLARE_FLAG(bool, trace_isolates); | 9 DECLARE_FLAG(bool, trace_isolates); |
10 | 10 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 } | 47 } |
48 OS::Print("[>] Posting message:\n" | 48 OS::Print("[>] Posting message:\n" |
49 "\tsource: %s\n" | 49 "\tsource: %s\n" |
50 "\treply_port: %lld\n" | 50 "\treply_port: %lld\n" |
51 "\tdest: %s\n" | 51 "\tdest: %s\n" |
52 "\tdest_port: %lld\n", | 52 "\tdest_port: %lld\n", |
53 source_name, message->reply_port(), name(), message->dest_port()); | 53 source_name, message->reply_port(), name(), message->dest_port()); |
54 } | 54 } |
55 | 55 |
56 Message::Priority priority = message->priority(); | 56 Message::Priority priority = message->priority(); |
57 { | 57 queue()->Enqueue(message); |
58 MonitorLocker ml(&monitor_); | 58 message = NULL; // Do not access message. May have been deleted. |
59 queue_->Enqueue(message); | |
60 monitor_.Notify(); | |
61 message = NULL; // Do not access message. May have been deleted. | |
62 } | |
63 | 59 |
64 // Invoke any custom message notification. | 60 // Invoke any custom message notification. |
65 MessageNotify(priority); | 61 MessageNotify(priority); |
66 } | 62 } |
67 | 63 |
68 | 64 |
69 Message* MessageHandler::DequeueNoWait() { | |
70 MonitorLocker ml(&monitor_); | |
71 return queue_->Dequeue(); | |
72 } | |
73 | |
74 | |
75 Message* MessageHandler::Dequeue(int64_t millis) { | |
76 ASSERT(millis >= 0); | |
77 MonitorLocker ml(&monitor_); | |
78 Message* result = queue_->Dequeue(); | |
79 if (result == NULL) { | |
80 // No message available at any priority. | |
81 monitor_.Wait(millis); | |
82 result = queue_->Dequeue(); | |
83 } | |
84 return result; | |
85 } | |
86 | |
87 | |
88 void MessageHandler::ClosePort(Dart_Port port) { | 65 void MessageHandler::ClosePort(Dart_Port port) { |
89 MonitorLocker ml(&monitor_); | 66 queue()->Flush(port); |
90 queue_->Flush(port); | |
91 } | 67 } |
92 | 68 |
93 | 69 |
94 void MessageHandler::CloseAllPorts() { | 70 void MessageHandler::CloseAllPorts() { |
95 MonitorLocker ml(&monitor_); | 71 queue()->FlushAll(); |
96 queue_->FlushAll(); | |
97 } | 72 } |
98 | 73 |
99 | 74 |
100 MessageQueue::MessageQueue() { | 75 MessageQueue::MessageQueue() { |
101 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | 76 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { |
102 head_[p] = NULL; | 77 head_[p] = NULL; |
103 tail_[p] = NULL; | 78 tail_[p] = NULL; |
104 } | 79 } |
105 } | 80 } |
106 | 81 |
107 | 82 |
108 MessageQueue::~MessageQueue() { | 83 MessageQueue::~MessageQueue() { |
109 // Ensure that all pending messages have been released. | 84 // Ensure that all pending messages have been released. |
110 #if defined(DEBUG) | 85 #if defined(DEBUG) |
111 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | 86 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { |
112 ASSERT(head_[p] == NULL); | 87 ASSERT(head_[p] == NULL); |
113 } | 88 } |
114 #endif | 89 #endif |
115 } | 90 } |
116 | 91 |
117 | 92 |
118 void MessageQueue::Enqueue(Message* msg) { | 93 void MessageQueue::Enqueue(Message* msg) { |
| 94 MonitorLocker ml(&monitor_); |
119 Message::Priority p = msg->priority(); | 95 Message::Priority p = msg->priority(); |
120 // Make sure messages are not reused. | 96 // Make sure messages are not reused. |
121 ASSERT(msg->next_ == NULL); | 97 ASSERT(msg->next_ == NULL); |
122 if (head_[p] == NULL) { | 98 if (head_[p] == NULL) { |
123 // Only element in the queue. | 99 // Only element in the queue. |
124 head_[p] = msg; | 100 head_[p] = msg; |
125 tail_[p] = msg; | 101 tail_[p] = msg; |
| 102 |
| 103 // We only need to notify if the queue was empty. |
| 104 monitor_.Notify(); |
126 } else { | 105 } else { |
127 ASSERT(tail_[p] != NULL); | 106 ASSERT(tail_[p] != NULL); |
128 // Append at the tail. | 107 // Append at the tail. |
129 tail_[p]->next_ = msg; | 108 tail_[p]->next_ = msg; |
130 tail_[p] = msg; | 109 tail_[p] = msg; |
131 } | 110 } |
132 } | 111 } |
133 | 112 |
| 113 Message* MessageQueue::DequeueNoWait() { |
| 114 MonitorLocker ml(&monitor_); |
| 115 return DequeueNoWaitHoldsLock(); |
| 116 } |
134 | 117 |
135 Message* MessageQueue::Dequeue() { | 118 Message* MessageQueue::DequeueNoWaitHoldsLock() { |
136 // Look for the highest priority available message. | 119 // Look for the highest priority available message. |
137 for (int p = Message::kNumPriorities-1; p >= Message::kFirstPriority; p--) { | 120 for (int p = Message::kNumPriorities-1; p >= Message::kFirstPriority; p--) { |
138 Message* result = head_[p]; | 121 Message* result = head_[p]; |
139 if (result != NULL) { | 122 if (result != NULL) { |
140 head_[p] = result->next_; | 123 head_[p] = result->next_; |
141 // The following update to tail_ is not strictly needed. | 124 // The following update to tail_ is not strictly needed. |
142 if (head_[p] == NULL) { | 125 if (head_[p] == NULL) { |
143 tail_[p] = NULL; | 126 tail_[p] = NULL; |
144 } | 127 } |
145 #if defined(DEBUG) | 128 #if defined(DEBUG) |
146 result->next_ = result; // Make sure to trigger ASSERT in Enqueue. | 129 result->next_ = result; // Make sure to trigger ASSERT in Enqueue. |
147 #endif // DEBUG | 130 #endif // DEBUG |
148 return result; | 131 return result; |
149 } | 132 } |
150 } | 133 } |
151 return NULL; | 134 return NULL; |
152 } | 135 } |
153 | 136 |
154 | 137 |
| 138 Message* MessageQueue::Dequeue(int64_t millis) { |
| 139 ASSERT(millis >= 0); |
| 140 MonitorLocker ml(&monitor_); |
| 141 Message* result = DequeueNoWaitHoldsLock(); |
| 142 if (result == NULL) { |
| 143 // No message available at any priority. |
| 144 monitor_.Wait(millis); |
| 145 result = DequeueNoWaitHoldsLock(); |
| 146 } |
| 147 return result; |
| 148 } |
| 149 |
| 150 |
155 void MessageQueue::Flush(Dart_Port port) { | 151 void MessageQueue::Flush(Dart_Port port) { |
| 152 MonitorLocker ml(&monitor_); |
156 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | 153 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { |
157 Message* cur = head_[p]; | 154 Message* cur = head_[p]; |
158 Message* prev = NULL; | 155 Message* prev = NULL; |
159 while (cur != NULL) { | 156 while (cur != NULL) { |
160 Message* next = cur->next_; | 157 Message* next = cur->next_; |
161 // If the message matches, then remove it from the queue and delete it. | 158 // If the message matches, then remove it from the queue and delete it. |
162 if (cur->dest_port() == port) { | 159 if (cur->dest_port() == port) { |
163 if (prev != NULL) { | 160 if (prev != NULL) { |
164 prev->next_ = next; | 161 prev->next_ = next; |
165 } else { | 162 } else { |
166 head_[p] = next; | 163 head_[p] = next; |
167 } | 164 } |
168 delete cur; | 165 delete cur; |
169 } else { | 166 } else { |
170 // Move prev forward. | 167 // Move prev forward. |
171 prev = cur; | 168 prev = cur; |
172 } | 169 } |
173 // Advance to the next message in the queue. | 170 // Advance to the next message in the queue. |
174 cur = next; | 171 cur = next; |
175 } | 172 } |
176 tail_[p] = prev; | 173 tail_[p] = prev; |
177 } | 174 } |
178 } | 175 } |
179 | 176 |
180 | 177 |
181 void MessageQueue::FlushAll() { | 178 void MessageQueue::FlushAll() { |
| 179 MonitorLocker ml(&monitor_); |
182 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | 180 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { |
183 Message* cur = head_[p]; | 181 Message* cur = head_[p]; |
184 head_[p] = NULL; | 182 head_[p] = NULL; |
185 tail_[p] = NULL; | 183 tail_[p] = NULL; |
186 while (cur != NULL) { | 184 while (cur != NULL) { |
187 Message* next = cur->next_; | 185 Message* next = cur->next_; |
188 delete cur; | 186 delete cur; |
189 cur = next; | 187 cur = next; |
190 } | 188 } |
191 } | 189 } |
192 } | 190 } |
193 | 191 |
194 | 192 |
195 } // namespace dart | 193 } // namespace dart |
OLD | NEW |