Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(872)

Unified Diff: runtime/vm/message_handler.cc

Issue 1665773004: Add necessary support functions so that embedders can implemented pause on start and exit (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/message_handler.h ('k') | runtime/vm/service.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/message_handler.cc
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index 30194cd5b4ec4a3074f690712f8bca1c2679a0b3..2340b65d766794da64779349e0449d8ab03a63a5 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,17 +282,33 @@ MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() {
}
-bool MessageHandler::HasOOBMessages() {
- MonitorLocker ml(&monitor_);
- return !oob_queue_->IsEmpty();
+bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const {
+ Isolate* owning_isolate = isolate();
+ if (owning_isolate == NULL) {
+ return false;
+ }
+ // If we are restarting or shutting down, we do not want to honor
+ // should_pause_on_start or should_pause_on_exit.
+ return (status != MessageHandler::kRestart &&
+ status != MessageHandler::kShutdown) &&
+ should_pause_on_start() && owning_isolate->is_runnable();
}
-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.
+bool MessageHandler::ShouldPauseOnExit(MessageStatus status) const {
+ Isolate* owning_isolate = isolate();
+ if (owning_isolate == NULL) {
+ return false;
+ }
return (status != MessageHandler::kRestart &&
- status != MessageHandler::kShutdown);
+ status != MessageHandler::kShutdown) &&
+ should_pause_on_exit() && owning_isolate->is_runnable();
+}
+
+
+bool MessageHandler::HasOOBMessages() {
+ MonitorLocker ml(&monitor_);
+ return !oob_queue_->IsEmpty();
}
@@ -294,28 +322,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(kOK)) {
+ 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 (ShouldPauseOnStart(status)) {
// 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 +361,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 (ShouldPauseOnExit(status)) {
+ 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);
+ status = HandleMessages(false, false);
}
- if (ShouldPause(status) && pause_on_exit()) {
+ if (ShouldPauseOnExit(status)) {
// 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 +452,74 @@ void MessageHandler::decrement_live_ports() {
}
+void MessageHandler::PausedOnStart(bool paused) {
+ MonitorLocker ml(&monitor_);
+ PausedOnStartLocked(paused);
+}
+
+
+void MessageHandler::PausedOnStartLocked(bool paused) {
+ if (paused) {
+ ASSERT(!is_paused_on_start_);
+ is_paused_on_start_ = true;
+ paused_timestamp_ = OS::GetCurrentTimeMillis();
+ } else {
+ ASSERT(is_paused_on_start_);
+ 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) {
+ ASSERT(!is_paused_on_exit_);
+ is_paused_on_exit_ = true;
+ paused_timestamp_ = OS::GetCurrentTimeMillis();
+ } else {
+ ASSERT(is_paused_on_exit_);
+ 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) {
}
« no previous file with comments | « runtime/vm/message_handler.h ('k') | runtime/vm/service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698