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 | 6 |
7 #include "vm/dart.h" | 7 #include "vm/dart.h" |
8 #include "vm/lockers.h" | 8 #include "vm/lockers.h" |
9 #include "vm/object.h" | 9 #include "vm/object.h" |
10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 return message; | 169 return message; |
170 } | 170 } |
171 | 171 |
172 | 172 |
173 void MessageHandler::ClearOOBQueue() { | 173 void MessageHandler::ClearOOBQueue() { |
174 oob_queue_->Clear(); | 174 oob_queue_->Clear(); |
175 } | 175 } |
176 | 176 |
177 | 177 |
178 MessageHandler::MessageStatus MessageHandler::HandleMessages( | 178 MessageHandler::MessageStatus MessageHandler::HandleMessages( |
| 179 MonitorLocker* ml, |
179 bool allow_normal_messages, | 180 bool allow_normal_messages, |
180 bool allow_multiple_normal_messages) { | 181 bool allow_multiple_normal_messages) { |
181 // TODO(turnidge): Add assert that monitor_ is held here. | 182 // TODO(turnidge): Add assert that monitor_ is held here. |
182 | 183 |
183 // If isolate() returns NULL StartIsolateScope does nothing. | 184 // If isolate() returns NULL StartIsolateScope does nothing. |
184 StartIsolateScope start_isolate(isolate()); | 185 StartIsolateScope start_isolate(isolate()); |
185 | 186 |
186 MessageStatus max_status = kOK; | 187 MessageStatus max_status = kOK; |
187 Message::Priority min_priority = ((allow_normal_messages && !paused()) | 188 Message::Priority min_priority = ((allow_normal_messages && !paused()) |
188 ? Message::kNormalPriority | 189 ? Message::kNormalPriority |
189 : Message::kOOBPriority); | 190 : Message::kOOBPriority); |
190 Message* message = DequeueMessage(min_priority); | 191 Message* message = DequeueMessage(min_priority); |
191 while (message != NULL) { | 192 while (message != NULL) { |
192 intptr_t message_len = message->len(); | 193 intptr_t message_len = message->len(); |
193 if (FLAG_trace_isolates) { | 194 if (FLAG_trace_isolates) { |
194 OS::Print("[<] Handling message:\n" | 195 OS::Print("[<] Handling message:\n" |
195 "\tlen: %" Pd "\n" | 196 "\tlen: %" Pd "\n" |
196 "\thandler: %s\n" | 197 "\thandler: %s\n" |
197 "\tport: %" Pd64 "\n", | 198 "\tport: %" Pd64 "\n", |
198 message_len, name(), message->dest_port()); | 199 message_len, name(), message->dest_port()); |
199 } | 200 } |
200 | 201 |
201 // Release the monitor_ temporarily while we handle the message. | 202 // Release the monitor_ temporarily while we handle the message. |
202 // The monitor was acquired in MessageHandler::TaskCallback(). | 203 // The monitor was acquired in MessageHandler::TaskCallback(). |
203 monitor_.Exit(); | 204 ml->Exit(); |
204 Message::Priority saved_priority = message->priority(); | 205 Message::Priority saved_priority = message->priority(); |
205 Dart_Port saved_dest_port = message->dest_port(); | 206 Dart_Port saved_dest_port = message->dest_port(); |
206 MessageStatus status = HandleMessage(message); | 207 MessageStatus status = HandleMessage(message); |
207 if (status > max_status) { | 208 if (status > max_status) { |
208 max_status = status; | 209 max_status = status; |
209 } | 210 } |
210 message = NULL; // May be deleted by now. | 211 message = NULL; // May be deleted by now. |
211 monitor_.Enter(); | 212 ml->Enter(); |
212 if (FLAG_trace_isolates) { | 213 if (FLAG_trace_isolates) { |
213 OS::Print("[.] Message handled (%s):\n" | 214 OS::Print("[.] Message handled (%s):\n" |
214 "\tlen: %" Pd "\n" | 215 "\tlen: %" Pd "\n" |
215 "\thandler: %s\n" | 216 "\thandler: %s\n" |
216 "\tport: %" Pd64 "\n", | 217 "\tport: %" Pd64 "\n", |
217 MessageStatusString(status), | 218 MessageStatusString(status), |
218 message_len, name(), saved_dest_port); | 219 message_len, name(), saved_dest_port); |
219 } | 220 } |
220 // If we are shutting down, do not process any more messages. | 221 // If we are shutting down, do not process any more messages. |
221 if (status == kShutdown) { | 222 if (status == kShutdown) { |
(...skipping 25 matching lines...) Expand all Loading... |
247 | 248 |
248 | 249 |
249 MessageHandler::MessageStatus MessageHandler::HandleNextMessage() { | 250 MessageHandler::MessageStatus MessageHandler::HandleNextMessage() { |
250 // We can only call HandleNextMessage when this handler is not | 251 // We can only call HandleNextMessage when this handler is not |
251 // assigned to a thread pool. | 252 // assigned to a thread pool. |
252 MonitorLocker ml(&monitor_); | 253 MonitorLocker ml(&monitor_); |
253 ASSERT(pool_ == NULL); | 254 ASSERT(pool_ == NULL); |
254 #if defined(DEBUG) | 255 #if defined(DEBUG) |
255 CheckAccess(); | 256 CheckAccess(); |
256 #endif | 257 #endif |
257 return HandleMessages(true, false); | 258 return HandleMessages(&ml, true, false); |
258 } | 259 } |
259 | 260 |
260 | 261 |
261 MessageHandler::MessageStatus MessageHandler::HandleAllMessages() { | 262 MessageHandler::MessageStatus MessageHandler::HandleAllMessages() { |
262 // We can only call HandleAllMessages when this handler is not | 263 // We can only call HandleAllMessages when this handler is not |
263 // assigned to a thread pool. | 264 // assigned to a thread pool. |
264 MonitorLocker ml(&monitor_); | 265 MonitorLocker ml(&monitor_); |
265 ASSERT(pool_ == NULL); | 266 ASSERT(pool_ == NULL); |
266 #if defined(DEBUG) | 267 #if defined(DEBUG) |
267 CheckAccess(); | 268 CheckAccess(); |
268 #endif | 269 #endif |
269 return HandleMessages(true, true); | 270 return HandleMessages(&ml, true, true); |
270 } | 271 } |
271 | 272 |
272 | 273 |
273 MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() { | 274 MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() { |
274 if (!oob_message_handling_allowed_) { | 275 if (!oob_message_handling_allowed_) { |
275 return kOK; | 276 return kOK; |
276 } | 277 } |
277 MonitorLocker ml(&monitor_); | 278 MonitorLocker ml(&monitor_); |
278 #if defined(DEBUG) | 279 #if defined(DEBUG) |
279 CheckAccess(); | 280 CheckAccess(); |
280 #endif | 281 #endif |
281 return HandleMessages(false, false); | 282 return HandleMessages(&ml, false, false); |
282 } | 283 } |
283 | 284 |
284 | 285 |
285 bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const { | 286 bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const { |
286 Isolate* owning_isolate = isolate(); | 287 Isolate* owning_isolate = isolate(); |
287 if (owning_isolate == NULL) { | 288 if (owning_isolate == NULL) { |
288 return false; | 289 return false; |
289 } | 290 } |
290 // If we are restarting or shutting down, we do not want to honor | 291 // If we are restarting or shutting down, we do not want to honor |
291 // should_pause_on_start or should_pause_on_exit. | 292 // should_pause_on_start or should_pause_on_exit. |
(...skipping 28 matching lines...) Expand all Loading... |
320 // We will occasionally release and reacquire this monitor in this | 321 // We will occasionally release and reacquire this monitor in this |
321 // function. Whenever we reacquire the monitor we *must* process | 322 // function. Whenever we reacquire the monitor we *must* process |
322 // all pending OOB messages, or we may miss a request for vm | 323 // all pending OOB messages, or we may miss a request for vm |
323 // shutdown. | 324 // shutdown. |
324 MonitorLocker ml(&monitor_); | 325 MonitorLocker ml(&monitor_); |
325 if (ShouldPauseOnStart(kOK)) { | 326 if (ShouldPauseOnStart(kOK)) { |
326 if (!is_paused_on_start()) { | 327 if (!is_paused_on_start()) { |
327 PausedOnStartLocked(true); | 328 PausedOnStartLocked(true); |
328 } | 329 } |
329 // More messages may have come in before we (re)acquired the monitor. | 330 // More messages may have come in before we (re)acquired the monitor. |
330 status = HandleMessages(false, false); | 331 status = HandleMessages(&ml, false, false); |
331 if (ShouldPauseOnStart(status)) { | 332 if (ShouldPauseOnStart(status)) { |
332 // Still paused. | 333 // Still paused. |
333 ASSERT(oob_queue_->IsEmpty()); | 334 ASSERT(oob_queue_->IsEmpty()); |
334 task_ = NULL; // No task in queue. | 335 task_ = NULL; // No task in queue. |
335 return; | 336 return; |
336 } else { | 337 } else { |
337 PausedOnStartLocked(false); | 338 PausedOnStartLocked(false); |
338 } | 339 } |
339 } | 340 } |
340 | 341 |
341 if (status == kOK) { | 342 if (status == kOK) { |
342 if (start_callback_) { | 343 if (start_callback_) { |
343 // Initialize the message handler by running its start function, | 344 // Initialize the message handler by running its start function, |
344 // if we have one. For an isolate, this will run the isolate's | 345 // if we have one. For an isolate, this will run the isolate's |
345 // main() function. | 346 // main() function. |
346 // | 347 // |
347 // Release the monitor_ temporarily while we call the start callback. | 348 // Release the monitor_ temporarily while we call the start callback. |
348 monitor_.Exit(); | 349 ml.Exit(); |
349 status = start_callback_(callback_data_); | 350 status = start_callback_(callback_data_); |
350 ASSERT(Isolate::Current() == NULL); | 351 ASSERT(Isolate::Current() == NULL); |
351 start_callback_ = NULL; | 352 start_callback_ = NULL; |
352 monitor_.Enter(); | 353 ml.Enter(); |
353 } | 354 } |
354 | 355 |
355 // Handle any pending messages for this message handler. | 356 // Handle any pending messages for this message handler. |
356 if (status != kShutdown) { | 357 if (status != kShutdown) { |
357 status = HandleMessages((status == kOK), true); | 358 status = HandleMessages(&ml, (status == kOK), true); |
358 } | 359 } |
359 } | 360 } |
360 | 361 |
361 // The isolate exits when it encounters an error or when it no | 362 // The isolate exits when it encounters an error or when it no |
362 // longer has live ports. | 363 // longer has live ports. |
363 if (status != kOK || !HasLivePorts()) { | 364 if (status != kOK || !HasLivePorts()) { |
364 if (ShouldPauseOnExit(status)) { | 365 if (ShouldPauseOnExit(status)) { |
365 if (!is_paused_on_exit()) { | 366 if (!is_paused_on_exit()) { |
366 if (FLAG_trace_service_pause_events) { | 367 if (FLAG_trace_service_pause_events) { |
367 OS::PrintErr("Isolate %s paused before exiting. " | 368 OS::PrintErr("Isolate %s paused before exiting. " |
368 "Use the Observatory to release it.\n", name()); | 369 "Use the Observatory to release it.\n", name()); |
369 } | 370 } |
370 PausedOnExitLocked(true); | 371 PausedOnExitLocked(true); |
371 // More messages may have come in while we released the monitor. | 372 // More messages may have come in while we released the monitor. |
372 status = HandleMessages(false, false); | 373 status = HandleMessages(&ml, false, false); |
373 } | 374 } |
374 if (ShouldPauseOnExit(status)) { | 375 if (ShouldPauseOnExit(status)) { |
375 // Still paused. | 376 // Still paused. |
376 ASSERT(oob_queue_->IsEmpty()); | 377 ASSERT(oob_queue_->IsEmpty()); |
377 task_ = NULL; // No task in queue. | 378 task_ = NULL; // No task in queue. |
378 return; | 379 return; |
379 } else { | 380 } else { |
380 PausedOnExitLocked(false); | 381 PausedOnExitLocked(false); |
381 } | 382 } |
382 } | 383 } |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 | 548 |
548 | 549 |
549 void MessageHandler::AcquireQueues(AcquiredQueues* acquired_queues) { | 550 void MessageHandler::AcquireQueues(AcquiredQueues* acquired_queues) { |
550 ASSERT(acquired_queues != NULL); | 551 ASSERT(acquired_queues != NULL); |
551 // No double dipping. | 552 // No double dipping. |
552 ASSERT(acquired_queues->handler_ == NULL); | 553 ASSERT(acquired_queues->handler_ == NULL); |
553 acquired_queues->Reset(this); | 554 acquired_queues->Reset(this); |
554 } | 555 } |
555 | 556 |
556 } // namespace dart | 557 } // namespace dart |
OLD | NEW |