| 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;
|
|
|