Index: runtime/vm/message_handler.cc |
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc |
index 6a473dd74033f4c6d019be2437de0c7a8ec29aa9..d330c0f64a68d462b6ccc39ae5c1bcf20c653d9a 100644 |
--- a/runtime/vm/message_handler.cc |
+++ b/runtime/vm/message_handler.cc |
@@ -235,6 +235,7 @@ void MessageHandler::TaskCallback() { |
ASSERT(Isolate::Current() == NULL); |
bool ok = true; |
bool run_end_callback = false; |
+ bool notify_paused_on_exit = false; |
{ |
MonitorLocker ml(&monitor_); |
// Initialize the message handler by running its start function, |
@@ -242,7 +243,12 @@ void MessageHandler::TaskCallback() { |
// main() function. |
if (pause_on_start()) { |
if (!paused_on_start_) { |
+ // Temporarily drop the lock 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(); |
paused_on_start_ = true; |
} |
HandleMessages(false, false); |
@@ -278,7 +284,7 @@ void MessageHandler::TaskCallback() { |
OS::PrintErr("Isolate %s paused before exiting. " |
"Use the Observatory to release it.\n", name()); |
} |
- NotifyPauseOnExit(); |
+ notify_paused_on_exit = true; |
paused_on_exit_ = true; |
} |
} else { |
@@ -294,6 +300,10 @@ void MessageHandler::TaskCallback() { |
} |
} |
} |
+ // At this point we no longer hold the message handler lock. |
+ if (notify_paused_on_exit) { |
+ NotifyPauseOnExit(); |
+ } |
if (run_end_callback && end_callback_ != NULL) { |
end_callback_(callback_data_); |
// The handler may have been deleted after this point. |