Index: runtime/vm/isolate.cc |
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc |
index 7d74fb682cfc934c5fe997723aebe1de3de57c4e..957888655e56b2fe34ef9d1cb1a417a412ea1769 100644 |
--- a/runtime/vm/isolate.cc |
+++ b/runtime/vm/isolate.cc |
@@ -283,7 +283,8 @@ RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { |
} |
break; |
} |
- case Isolate::kKillMsg: { |
+ case Isolate::kKillMsg: |
+ case Isolate::kInternalKillMsg: { |
// [ OOB, kKillMsg, terminate capability, priority ] |
if (message.Length() != 4) return Error::null(); |
Object& obj = Object::Handle(I, message.At(3)); |
@@ -293,9 +294,22 @@ RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { |
obj = message.At(2); |
// Signal that the isolate should stop execution. |
if (I->VerifyTerminateCapability(obj)) { |
- const String& msg = String::Handle(String::New( |
- "isolate terminated by Isolate.kill")); |
- return UnwindError::New(msg); |
+ if (msg_type == Isolate::kKillMsg) { |
+ const String& msg = String::Handle(String::New( |
+ "isolate terminated by Isolate.kill")); |
+ const UnwindError& error = |
+ UnwindError::Handle(UnwindError::New(msg)); |
+ error.set_is_user_initiated(true); |
+ return error.raw(); |
+ } else { |
+ // TODO(turnidge): We should give the message handler a way |
+ // to detect when an isolate is unwinding. |
+ I->message_handler()->set_pause_on_start(false); |
+ I->message_handler()->set_pause_on_exit(false); |
+ const String& msg = String::Handle(String::New( |
+ "isolate terminated by vm")); |
+ return UnwindError::New(msg); |
+ } |
} else { |
return Error::null(); |
} |
@@ -1414,8 +1428,7 @@ static void ShutdownIsolate(uword parameter) { |
ASSERT(thread->isolate() == isolate); |
StackZone zone(thread); |
HandleScope handle_scope(thread); |
- Error& error = Error::Handle(); |
- error = isolate->object_store()->sticky_error(); |
+ const Error& error = Error::Handle(isolate->object_store()->sticky_error()); |
if (!error.IsNull() && !error.IsUnwindError()) { |
OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); |
} |
@@ -1468,13 +1481,10 @@ RawError* Isolate::HandleInterrupts() { |
OS::Print("[!] Terminating isolate due to OOB message:\n" |
"\tisolate: %s\n", name()); |
} |
- // TODO(turnidge): If the isolate is being killed by |
- // Isolate.kill, then we probably want to respect pause_on_exit. |
- // If the isolate is being killed due to vm restart we don't. |
- message_handler()->set_pause_on_start(false); |
- message_handler()->set_pause_on_exit(false); |
- const String& msg = String::Handle(String::New("isolate terminated")); |
- return UnwindError::New(msg); |
+ const Error& error = Error::Handle(object_store()->sticky_error()); |
+ object_store()->clear_sticky_error(); |
+ ASSERT(!error.IsNull()); |
+ return error.raw(); |
} |
} |
return Error::null(); |
@@ -1567,10 +1577,12 @@ void Isolate::LowLevelShutdown() { |
// Notify exit listeners that this isolate is shutting down. |
if (object_store() != NULL) { |
- // TODO(turnidge): If the isolate is being killed by Isolate.kill, |
- // then we want to notify event listeners. If the isolate is |
- // being killed due to vm restart we probably don't. |
- NotifyExitListeners(); |
+ const Error& error = Error::Handle(object_store()->sticky_error()); |
+ if (error.IsNull() || |
+ !error.IsUnwindError() || |
+ UnwindError::Cast(error).is_user_initiated()) { |
+ NotifyExitListeners(); |
+ } |
} |
// Clean up debugger resources. |
@@ -2295,10 +2307,10 @@ void Isolate::KillLocked() { |
oob.value.as_int32 = Message::kIsolateLibOOBMsg; |
list_values[0] = &oob; |
- Dart_CObject kill; |
- kill.type = Dart_CObject_kInt32; |
- kill.value.as_int32 = Isolate::kKillMsg; |
- list_values[1] = &kill; |
+ Dart_CObject msg_type; |
+ msg_type.type = Dart_CObject_kInt32; |
+ msg_type.value.as_int32 = Isolate::kInternalKillMsg; |
+ list_values[1] = &msg_type; |
Dart_CObject cap; |
cap.type = Dart_CObject_kCapability; |