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