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) { |
} |