Chromium Code Reviews| Index: runtime/vm/message_handler.cc |
| diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc |
| index 30194cd5b4ec4a3074f690712f8bca1c2679a0b3..af45720851e9ebce6ccf5f2568d8b72a6165c715 100644 |
| --- a/runtime/vm/message_handler.cc |
| +++ b/runtime/vm/message_handler.cc |
| @@ -61,10 +61,10 @@ MessageHandler::MessageHandler() |
| oob_message_handling_allowed_(true), |
| live_ports_(0), |
| paused_(0), |
| - pause_on_start_(false), |
| - pause_on_exit_(false), |
| - paused_on_start_(false), |
| - paused_on_exit_(false), |
| + should_pause_on_start_(false), |
| + should_pause_on_exit_(false), |
| + is_paused_on_start_(false), |
| + is_paused_on_exit_(false), |
| paused_timestamp_(-1), |
| pool_(NULL), |
| task_(NULL), |
| @@ -258,6 +258,18 @@ MessageHandler::MessageStatus MessageHandler::HandleNextMessage() { |
| } |
| +MessageHandler::MessageStatus MessageHandler::HandleAllMessages() { |
| + // We can only call HandleAllMessages when this handler is not |
| + // assigned to a thread pool. |
| + MonitorLocker ml(&monitor_); |
| + ASSERT(pool_ == NULL); |
| +#if defined(DEBUG) |
| + CheckAccess(); |
| +#endif |
| + return HandleMessages(true, true); |
| +} |
| + |
| + |
| MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() { |
| if (!oob_message_handling_allowed_) { |
| return kOK; |
| @@ -270,6 +282,24 @@ MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() { |
| } |
| +bool MessageHandler::ShouldPauseOnStart() const { |
| + Isolate* owning_isolate = isolate(); |
| + if (owning_isolate == NULL) { |
| + return false; |
| + } |
| + return should_pause_on_start() && owning_isolate->is_runnable(); |
| +} |
| + |
| + |
| +bool MessageHandler::ShouldPauseOnExit() const { |
| + Isolate* owning_isolate = isolate(); |
| + if (owning_isolate == NULL) { |
| + return false; |
| + } |
| + return should_pause_on_exit() && owning_isolate->is_runnable(); |
| +} |
| + |
| + |
| bool MessageHandler::HasOOBMessages() { |
| MonitorLocker ml(&monitor_); |
| return !oob_queue_->IsEmpty(); |
| @@ -278,7 +308,7 @@ bool MessageHandler::HasOOBMessages() { |
| static bool ShouldPause(MessageHandler::MessageStatus status) { |
| // If we are restarting or shutting down, we do not want to honor |
| - // pause_on_start or pause_on_exit. |
| + // should_pause_on_start or should_pause_on_exit. |
| return (status != MessageHandler::kRestart && |
| status != MessageHandler::kShutdown); |
|
turnidge
2016/02/03 23:17:56
I wonder if we can fold ShouldPause() into ShoudlP
Cutch
2016/02/03 23:25:07
Done.
|
| } |
| @@ -294,28 +324,19 @@ void MessageHandler::TaskCallback() { |
| // all pending OOB messages, or we may miss a request for vm |
| // shutdown. |
| MonitorLocker ml(&monitor_); |
| - if (pause_on_start()) { |
| - if (!paused_on_start_) { |
| - // Temporarily release the monitor when calling out to |
| - // NotifyPauseOnStart. This avoids a dead lock that can occur |
| - // when this message handler tries to post a message while a |
| - // message is being posted to it. |
| - paused_on_start_ = true; |
| - paused_timestamp_ = OS::GetCurrentTimeMillis(); |
| - monitor_.Exit(); |
| - NotifyPauseOnStart(); |
| - monitor_.Enter(); |
| + if (ShouldPauseOnStart()) { |
| + if (!is_paused_on_start_) { |
| + PausedOnStartLocked(true); |
| } |
| // More messages may have come in before we (re)acquired the monitor. |
| status = HandleMessages(false, false); |
| - if (ShouldPause(status) && pause_on_start()) { |
| + if (ShouldPause(status) && ShouldPauseOnStart()) { |
| // Still paused. |
| ASSERT(oob_queue_->IsEmpty()); |
| task_ = NULL; // No task in queue. |
| return; |
| } else { |
| - paused_on_start_ = false; |
| - paused_timestamp_ = -1; |
| + PausedOnStartLocked(false); |
| } |
| } |
| @@ -342,33 +363,23 @@ void MessageHandler::TaskCallback() { |
| // The isolate exits when it encounters an error or when it no |
| // longer has live ports. |
| if (status != kOK || !HasLivePorts()) { |
| - if (ShouldPause(status) && pause_on_exit()) { |
| - if (!paused_on_exit_) { |
| + if (ShouldPause(status) && ShouldPauseOnExit()) { |
| + if (!is_paused_on_exit_) { |
| if (FLAG_trace_service_pause_events) { |
| OS::PrintErr("Isolate %s paused before exiting. " |
| "Use the Observatory to release it.\n", name()); |
| } |
| - // Temporarily release the monitor when calling out to |
| - // NotifyPauseOnExit. This avoids a dead lock that can |
| - // occur when this message handler tries to post a message |
| - // while a message is being posted to it. |
| - paused_on_exit_ = true; |
| - paused_timestamp_ = OS::GetCurrentTimeMillis(); |
| - monitor_.Exit(); |
| - NotifyPauseOnExit(); |
| - monitor_.Enter(); |
| - |
| + PausedOnExitLocked(true); |
| // More messages may have come in while we released the monitor. |
| HandleMessages(false, false); |
| } |
| - if (ShouldPause(status) && pause_on_exit()) { |
| + if (ShouldPause(status) && ShouldPauseOnExit()) { |
| // Still paused. |
| ASSERT(oob_queue_->IsEmpty()); |
| task_ = NULL; // No task in queue. |
| return; |
| } else { |
| - paused_on_exit_ = false; |
| - paused_timestamp_ = -1; |
| + PausedOnExitLocked(false); |
| } |
| } |
| if (FLAG_trace_isolates) { |
| @@ -443,6 +454,70 @@ void MessageHandler::decrement_live_ports() { |
| } |
| +void MessageHandler::PausedOnStart(bool paused) { |
| + MonitorLocker ml(&monitor_); |
| + PausedOnStartLocked(paused); |
| +} |
| + |
| + |
| +void MessageHandler::PausedOnStartLocked(bool paused) { |
| + if (paused) { |
|
turnidge
2016/02/03 23:17:57
Do we want to ASSERT(!is_paused_on_start_)?
Simil
Cutch
2016/02/03 23:25:07
Done.
|
| + is_paused_on_start_ = true; |
| + paused_timestamp_ = OS::GetCurrentTimeMillis(); |
| + } else { |
| + is_paused_on_start_ = false; |
| + paused_timestamp_ = -1; |
| + } |
| + if (is_paused_on_start_) { |
| + // Temporarily release the monitor when calling out to |
| + // NotifyPauseOnStart. This avoids a dead lock that can occur |
| + // when this message handler tries to post a message while a |
| + // message is being posted to it. |
| + monitor_.Exit(); |
| + NotifyPauseOnStart(); |
| + monitor_.Enter(); |
| + } else { |
| + // Resumed. Clear the resume request of the owning isolate. |
| + Isolate* owning_isolate = isolate(); |
| + if (owning_isolate != NULL) { |
| + owning_isolate->GetAndClearResumeRequest(); |
| + } |
| + } |
| +} |
| + |
| + |
| +void MessageHandler::PausedOnExit(bool paused) { |
| + MonitorLocker ml(&monitor_); |
| + PausedOnExitLocked(paused); |
| +} |
| + |
| + |
| +void MessageHandler::PausedOnExitLocked(bool paused) { |
| + if (paused) { |
| + is_paused_on_exit_ = true; |
| + paused_timestamp_ = OS::GetCurrentTimeMillis(); |
| + } else { |
| + is_paused_on_exit_ = false; |
| + paused_timestamp_ = -1; |
| + } |
| + if (is_paused_on_exit_) { |
| + // Temporarily release the monitor when calling out to |
| + // NotifyPauseOnExit. This avoids a dead lock that can |
| + // occur when this message handler tries to post a message |
| + // while a message is being posted to it. |
| + monitor_.Exit(); |
| + NotifyPauseOnExit(); |
| + monitor_.Enter(); |
| + } else { |
| + // Resumed. Clear the resume request of the owning isolate. |
| + Isolate* owning_isolate = isolate(); |
| + if (owning_isolate != NULL) { |
| + owning_isolate->GetAndClearResumeRequest(); |
| + } |
| + } |
| +} |
| + |
| + |
| MessageHandler::AcquiredQueues::AcquiredQueues() |
| : handler_(NULL) { |
| } |