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 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 MessageStatus status = kOK; | 318 MessageStatus status = kOK; |
319 bool run_end_callback = false; | 319 bool run_end_callback = false; |
320 { | 320 { |
321 // We will occasionally release and reacquire this monitor in this | 321 // We will occasionally release and reacquire this monitor in this |
322 // function. Whenever we reacquire the monitor we *must* process | 322 // function. Whenever we reacquire the monitor we *must* process |
323 // 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 |
324 // shutdown. | 324 // shutdown. |
325 MonitorLocker ml(&monitor_); | 325 MonitorLocker ml(&monitor_); |
326 if (ShouldPauseOnStart(kOK)) { | 326 if (ShouldPauseOnStart(kOK)) { |
327 if (!is_paused_on_start()) { | 327 if (!is_paused_on_start()) { |
328 PausedOnStartLocked(true); | 328 PausedOnStartLocked(&ml, true); |
329 } | 329 } |
330 // 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. |
331 status = HandleMessages(&ml, false, false); | 331 status = HandleMessages(&ml, false, false); |
332 if (ShouldPauseOnStart(status)) { | 332 if (ShouldPauseOnStart(status)) { |
333 // Still paused. | 333 // Still paused. |
334 ASSERT(oob_queue_->IsEmpty()); | 334 ASSERT(oob_queue_->IsEmpty()); |
335 task_ = NULL; // No task in queue. | 335 task_ = NULL; // No task in queue. |
336 return; | 336 return; |
337 } else { | 337 } else { |
338 PausedOnStartLocked(false); | 338 PausedOnStartLocked(&ml, false); |
339 } | 339 } |
340 } | 340 } |
341 | 341 |
342 if (status == kOK) { | 342 if (status == kOK) { |
343 if (start_callback_) { | 343 if (start_callback_) { |
344 // Initialize the message handler by running its start function, | 344 // Initialize the message handler by running its start function, |
345 // 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 |
346 // main() function. | 346 // main() function. |
347 // | 347 // |
348 // Release the monitor_ temporarily while we call the start callback. | 348 // Release the monitor_ temporarily while we call the start callback. |
(...skipping 12 matching lines...) Expand all Loading... |
361 | 361 |
362 // 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 |
363 // longer has live ports. | 363 // longer has live ports. |
364 if (status != kOK || !HasLivePorts()) { | 364 if (status != kOK || !HasLivePorts()) { |
365 if (ShouldPauseOnExit(status)) { | 365 if (ShouldPauseOnExit(status)) { |
366 if (!is_paused_on_exit()) { | 366 if (!is_paused_on_exit()) { |
367 if (FLAG_trace_service_pause_events) { | 367 if (FLAG_trace_service_pause_events) { |
368 OS::PrintErr("Isolate %s paused before exiting. " | 368 OS::PrintErr("Isolate %s paused before exiting. " |
369 "Use the Observatory to release it.\n", name()); | 369 "Use the Observatory to release it.\n", name()); |
370 } | 370 } |
371 PausedOnExitLocked(true); | 371 PausedOnExitLocked(&ml, true); |
372 // More messages may have come in while we released the monitor. | 372 // More messages may have come in while we released the monitor. |
373 status = HandleMessages(&ml, false, false); | 373 status = HandleMessages(&ml, false, false); |
374 } | 374 } |
375 if (ShouldPauseOnExit(status)) { | 375 if (ShouldPauseOnExit(status)) { |
376 // Still paused. | 376 // Still paused. |
377 ASSERT(oob_queue_->IsEmpty()); | 377 ASSERT(oob_queue_->IsEmpty()); |
378 task_ = NULL; // No task in queue. | 378 task_ = NULL; // No task in queue. |
379 return; | 379 return; |
380 } else { | 380 } else { |
381 PausedOnExitLocked(false); | 381 PausedOnExitLocked(&ml, false); |
382 } | 382 } |
383 } | 383 } |
384 if (FLAG_trace_isolates) { | 384 if (FLAG_trace_isolates) { |
385 if (status != kOK && isolate() != NULL) { | 385 if (status != kOK && isolate() != NULL) { |
386 const Error& error = Error::Handle(thread()->sticky_error()); | 386 const Error& error = Error::Handle(thread()->sticky_error()); |
387 OS::Print("[-] Stopping message handler (%s):\n" | 387 OS::Print("[-] Stopping message handler (%s):\n" |
388 "\thandler: %s\n" | 388 "\thandler: %s\n" |
389 "\terror: %s\n", | 389 "\terror: %s\n", |
390 MessageStatusString(status), name(), error.ToCString()); | 390 MessageStatusString(status), name(), error.ToCString()); |
391 } else { | 391 } else { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 MonitorLocker ml(&monitor_); | 447 MonitorLocker ml(&monitor_); |
448 #if defined(DEBUG) | 448 #if defined(DEBUG) |
449 CheckAccess(); | 449 CheckAccess(); |
450 #endif | 450 #endif |
451 live_ports_--; | 451 live_ports_--; |
452 } | 452 } |
453 | 453 |
454 | 454 |
455 void MessageHandler::PausedOnStart(bool paused) { | 455 void MessageHandler::PausedOnStart(bool paused) { |
456 MonitorLocker ml(&monitor_); | 456 MonitorLocker ml(&monitor_); |
457 PausedOnStartLocked(paused); | 457 PausedOnStartLocked(&ml, paused); |
458 } | 458 } |
459 | 459 |
460 | 460 |
461 void MessageHandler::PausedOnStartLocked(bool paused) { | 461 void MessageHandler::PausedOnStartLocked(MonitorLocker* ml, bool paused) { |
462 if (paused) { | 462 if (paused) { |
463 ASSERT(!is_paused_on_start_); | 463 ASSERT(!is_paused_on_start_); |
464 is_paused_on_start_ = true; | 464 is_paused_on_start_ = true; |
465 paused_timestamp_ = OS::GetCurrentTimeMillis(); | 465 paused_timestamp_ = OS::GetCurrentTimeMillis(); |
466 } else { | 466 } else { |
467 ASSERT(is_paused_on_start_); | 467 ASSERT(is_paused_on_start_); |
468 is_paused_on_start_ = false; | 468 is_paused_on_start_ = false; |
469 paused_timestamp_ = -1; | 469 paused_timestamp_ = -1; |
470 } | 470 } |
471 if (is_paused_on_start_) { | 471 if (is_paused_on_start_) { |
472 // Temporarily release the monitor when calling out to | 472 // Temporarily release the monitor when calling out to |
473 // NotifyPauseOnStart. This avoids a dead lock that can occur | 473 // NotifyPauseOnStart. This avoids a dead lock that can occur |
474 // when this message handler tries to post a message while a | 474 // when this message handler tries to post a message while a |
475 // message is being posted to it. | 475 // message is being posted to it. |
476 monitor_.Exit(); | 476 ml->Exit(); |
477 NotifyPauseOnStart(); | 477 NotifyPauseOnStart(); |
478 monitor_.Enter(); | 478 ml->Enter(); |
479 } else { | 479 } else { |
480 // Resumed. Clear the resume request of the owning isolate. | 480 // Resumed. Clear the resume request of the owning isolate. |
481 Isolate* owning_isolate = isolate(); | 481 Isolate* owning_isolate = isolate(); |
482 if (owning_isolate != NULL) { | 482 if (owning_isolate != NULL) { |
483 owning_isolate->GetAndClearResumeRequest(); | 483 owning_isolate->GetAndClearResumeRequest(); |
484 } | 484 } |
485 } | 485 } |
486 } | 486 } |
487 | 487 |
488 | 488 |
489 void MessageHandler::PausedOnExit(bool paused) { | 489 void MessageHandler::PausedOnExit(bool paused) { |
490 MonitorLocker ml(&monitor_); | 490 MonitorLocker ml(&monitor_); |
491 PausedOnExitLocked(paused); | 491 PausedOnExitLocked(&ml, paused); |
492 } | 492 } |
493 | 493 |
494 | 494 |
495 void MessageHandler::PausedOnExitLocked(bool paused) { | 495 void MessageHandler::PausedOnExitLocked(MonitorLocker* ml, bool paused) { |
496 if (paused) { | 496 if (paused) { |
497 ASSERT(!is_paused_on_exit_); | 497 ASSERT(!is_paused_on_exit_); |
498 is_paused_on_exit_ = true; | 498 is_paused_on_exit_ = true; |
499 paused_timestamp_ = OS::GetCurrentTimeMillis(); | 499 paused_timestamp_ = OS::GetCurrentTimeMillis(); |
500 } else { | 500 } else { |
501 ASSERT(is_paused_on_exit_); | 501 ASSERT(is_paused_on_exit_); |
502 is_paused_on_exit_ = false; | 502 is_paused_on_exit_ = false; |
503 paused_timestamp_ = -1; | 503 paused_timestamp_ = -1; |
504 } | 504 } |
505 if (is_paused_on_exit_) { | 505 if (is_paused_on_exit_) { |
506 // Temporarily release the monitor when calling out to | 506 // Temporarily release the monitor when calling out to |
507 // NotifyPauseOnExit. This avoids a dead lock that can | 507 // NotifyPauseOnExit. This avoids a dead lock that can |
508 // occur when this message handler tries to post a message | 508 // occur when this message handler tries to post a message |
509 // while a message is being posted to it. | 509 // while a message is being posted to it. |
510 monitor_.Exit(); | 510 ml->Exit(); |
511 NotifyPauseOnExit(); | 511 NotifyPauseOnExit(); |
512 monitor_.Enter(); | 512 ml->Enter(); |
513 } else { | 513 } else { |
514 // Resumed. Clear the resume request of the owning isolate. | 514 // Resumed. Clear the resume request of the owning isolate. |
515 Isolate* owning_isolate = isolate(); | 515 Isolate* owning_isolate = isolate(); |
516 if (owning_isolate != NULL) { | 516 if (owning_isolate != NULL) { |
517 owning_isolate->GetAndClearResumeRequest(); | 517 owning_isolate->GetAndClearResumeRequest(); |
518 } | 518 } |
519 } | 519 } |
520 } | 520 } |
521 | 521 |
522 | 522 |
523 MessageHandler::AcquiredQueues::AcquiredQueues() | 523 MessageHandler::AcquiredQueues::AcquiredQueues(MessageHandler* handler) |
524 : handler_(NULL) { | 524 : handler_(handler), ml_(&handler->monitor_) { |
| 525 ASSERT(handler != NULL); |
| 526 handler_->oob_message_handling_allowed_ = false; |
525 } | 527 } |
526 | 528 |
527 | 529 |
528 MessageHandler::AcquiredQueues::~AcquiredQueues() { | 530 MessageHandler::AcquiredQueues::~AcquiredQueues() { |
529 Reset(NULL); | |
530 } | |
531 | |
532 | |
533 void MessageHandler::AcquiredQueues::Reset(MessageHandler* handler) { | |
534 if (handler_ != NULL) { | |
535 // Release ownership. The OOB flag is set without holding the monitor. | |
536 handler_->monitor_.Exit(); | |
537 handler_->oob_message_handling_allowed_ = true; | |
538 } | |
539 handler_ = handler; | |
540 if (handler_ == NULL) { | |
541 return; | |
542 } | |
543 ASSERT(handler_ != NULL); | 531 ASSERT(handler_ != NULL); |
544 // Take ownership. The OOB flag is set without holding the monitor. | 532 handler_->oob_message_handling_allowed_ = true; |
545 handler_->oob_message_handling_allowed_ = false; | |
546 handler_->monitor_.Enter(); | |
547 } | |
548 | |
549 | |
550 void MessageHandler::AcquireQueues(AcquiredQueues* acquired_queues) { | |
551 ASSERT(acquired_queues != NULL); | |
552 // No double dipping. | |
553 ASSERT(acquired_queues->handler_ == NULL); | |
554 acquired_queues->Reset(this); | |
555 } | 533 } |
556 | 534 |
557 } // namespace dart | 535 } // namespace dart |
OLD | NEW |