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_handler.h" | 5 #include "vm/message_handler.h" |
6 #include "vm/port.h" | 6 #include "vm/port.h" |
7 #include "vm/dart.h" | 7 #include "vm/dart.h" |
8 | 8 |
9 namespace dart { | 9 namespace dart { |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 DISALLOW_COPY_AND_ASSIGN(MessageHandlerTask); | 28 DISALLOW_COPY_AND_ASSIGN(MessageHandlerTask); |
29 }; | 29 }; |
30 | 30 |
31 | 31 |
32 MessageHandler::MessageHandler() | 32 MessageHandler::MessageHandler() |
33 : queue_(new MessageQueue()), | 33 : queue_(new MessageQueue()), |
34 oob_queue_(new MessageQueue()), | 34 oob_queue_(new MessageQueue()), |
35 control_ports_(0), | 35 control_ports_(0), |
36 live_ports_(0), | 36 live_ports_(0), |
| 37 paused_(0), |
37 pause_on_start_(false), | 38 pause_on_start_(false), |
38 pause_on_exit_(false), | 39 pause_on_exit_(false), |
39 paused_on_exit_(false), | 40 paused_on_exit_(false), |
40 pool_(NULL), | 41 pool_(NULL), |
41 task_(NULL), | 42 task_(NULL), |
42 start_callback_(NULL), | 43 start_callback_(NULL), |
43 end_callback_(NULL), | 44 end_callback_(NULL), |
44 callback_data_(0) { | 45 callback_data_(0) { |
45 ASSERT(queue_ != NULL); | 46 ASSERT(queue_ != NULL); |
46 ASSERT(oob_queue_ != NULL); | 47 ASSERT(oob_queue_ != NULL); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 } | 120 } |
120 | 121 |
121 // Invoke any custom message notification. | 122 // Invoke any custom message notification. |
122 MessageNotify(saved_priority); | 123 MessageNotify(saved_priority); |
123 } | 124 } |
124 | 125 |
125 | 126 |
126 Message* MessageHandler::DequeueMessage(Message::Priority min_priority) { | 127 Message* MessageHandler::DequeueMessage(Message::Priority min_priority) { |
127 // TODO(turnidge): Add assert that monitor_ is held here. | 128 // TODO(turnidge): Add assert that monitor_ is held here. |
128 Message* message = oob_queue_->Dequeue(); | 129 Message* message = oob_queue_->Dequeue(); |
129 if (message == NULL && min_priority < Message::kOOBPriority) { | 130 if ((message == NULL) && (min_priority < Message::kOOBPriority)) { |
130 message = queue_->Dequeue(); | 131 message = queue_->Dequeue(); |
131 } | 132 } |
132 return message; | 133 return message; |
133 } | 134 } |
134 | 135 |
135 | 136 |
136 bool MessageHandler::HandleMessages(bool allow_normal_messages, | 137 bool MessageHandler::HandleMessages(bool allow_normal_messages, |
137 bool allow_multiple_normal_messages) { | 138 bool allow_multiple_normal_messages) { |
138 // TODO(turnidge): Add assert that monitor_ is held here. | 139 // TODO(turnidge): Add assert that monitor_ is held here. |
139 bool result = true; | 140 bool result = true; |
140 Message::Priority min_priority = (allow_normal_messages | 141 Message::Priority min_priority = (allow_normal_messages && !paused()) ? |
141 ? Message::kNormalPriority | 142 Message::kNormalPriority : Message::kOOBPriority; |
142 : Message::kOOBPriority); | |
143 Message* message = DequeueMessage(min_priority); | 143 Message* message = DequeueMessage(min_priority); |
144 while (message != NULL) { | 144 while (message != NULL) { |
145 if (FLAG_trace_isolates) { | 145 if (FLAG_trace_isolates) { |
146 OS::Print("[<] Handling message:\n" | 146 OS::Print("[<] Handling message:\n" |
147 "\thandler: %s\n" | 147 "\thandler: %s\n" |
148 "\tport: %" Pd64 "\n", | 148 "\tport: %" Pd64 "\n", |
149 name(), message->dest_port()); | 149 name(), message->dest_port()); |
150 } | 150 } |
151 | 151 |
152 // Release the monitor_ temporarily while we handle the message. | 152 // Release the monitor_ temporarily while we handle the message. |
153 // The monitor was acquired in MessageHandler::TaskCallback(). | 153 // The monitor was acquired in MessageHandler::TaskCallback(). |
154 monitor_.Exit(); | 154 monitor_.Exit(); |
155 Message::Priority saved_priority = message->priority(); | 155 Message::Priority saved_priority = message->priority(); |
156 result = HandleMessage(message); | 156 result = HandleMessage(message); |
157 monitor_.Enter(); | 157 monitor_.Enter(); |
158 if (FLAG_trace_isolates) { | 158 if (FLAG_trace_isolates) { |
159 OS::Print("[.] Message handled:\n" | 159 OS::Print("[.] Message handled:\n" |
160 "\thandler: %s\n" | 160 "\thandler: %s\n" |
161 "\tport: %" Pd64 "\n", | 161 "\tport: %" Pd64 "\n", |
162 name(), message->dest_port()); | 162 name(), message->dest_port()); |
163 } | 163 } |
164 if (!result) { | 164 if (!result) { |
165 // If we hit an error, we're done processing messages. | 165 // If we hit an error, we're done processing messages. |
166 break; | 166 break; |
167 } | 167 } |
168 if (!allow_multiple_normal_messages && | 168 // Some callers want to process only one normal message and then quit. At |
169 saved_priority == Message::kNormalPriority) { | 169 // the same time it is OK to process multiple OOB messages. |
170 // Some callers want to process only one normal message and then quit. | 170 if ((saved_priority == Message::kNormalPriority) && |
| 171 !allow_multiple_normal_messages) { |
171 break; | 172 break; |
172 } | 173 } |
| 174 |
| 175 // Reevaluate the minimum allowable priority as the paused state might |
| 176 // have changed as part of handling the message. |
| 177 min_priority = (allow_normal_messages && !paused()) ? |
| 178 Message::kNormalPriority : Message::kOOBPriority; |
173 message = DequeueMessage(min_priority); | 179 message = DequeueMessage(min_priority); |
174 } | 180 } |
175 return result; | 181 return result; |
176 } | 182 } |
177 | 183 |
178 | 184 |
179 bool MessageHandler::HandleNextMessage() { | 185 bool MessageHandler::HandleNextMessage() { |
180 // We can only call HandleNextMessage when this handler is not | 186 // We can only call HandleNextMessage when this handler is not |
181 // assigned to a thread pool. | 187 // assigned to a thread pool. |
182 MonitorLocker ml(&monitor_); | 188 MonitorLocker ml(&monitor_); |
(...skipping 26 matching lines...) Expand all Loading... |
209 if (pause_on_start()) { | 215 if (pause_on_start()) { |
210 HandleMessages(false, false); | 216 HandleMessages(false, false); |
211 if (pause_on_start()) { | 217 if (pause_on_start()) { |
212 // Still paused. | 218 // Still paused. |
213 task_ = NULL; // No task in queue. | 219 task_ = NULL; // No task in queue. |
214 return; | 220 return; |
215 } | 221 } |
216 } | 222 } |
217 | 223 |
218 if (start_callback_) { | 224 if (start_callback_) { |
| 225 // Release the monitor_ temporarily while we call the start callback. |
| 226 // The monitor was acquired with the MonitorLocker above. |
219 monitor_.Exit(); | 227 monitor_.Exit(); |
220 ok = start_callback_(callback_data_); | 228 ok = start_callback_(callback_data_); |
221 ASSERT(Isolate::Current() == NULL); | 229 ASSERT(Isolate::Current() == NULL); |
222 start_callback_ = NULL; | 230 start_callback_ = NULL; |
223 monitor_.Enter(); | 231 monitor_.Enter(); |
224 } | 232 } |
225 | 233 |
226 // Handle any pending messages for this message handler. | 234 // Handle any pending messages for this message handler. |
227 if (ok) { | 235 if (ok) { |
228 ok = HandleMessages(true, true); | 236 ok = HandleMessages(true, true); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 317 |
310 void MessageHandler::decrement_control_ports() { | 318 void MessageHandler::decrement_control_ports() { |
311 MonitorLocker ml(&monitor_); | 319 MonitorLocker ml(&monitor_); |
312 #if defined(DEBUG) | 320 #if defined(DEBUG) |
313 CheckAccess(); | 321 CheckAccess(); |
314 #endif | 322 #endif |
315 control_ports_--; | 323 control_ports_--; |
316 } | 324 } |
317 | 325 |
318 } // namespace dart | 326 } // namespace dart |
OLD | NEW |