Index: runtime/vm/isolate.cc |
=================================================================== |
--- runtime/vm/isolate.cc (revision 42195) |
+++ runtime/vm/isolate.cc (working copy) |
@@ -106,13 +106,17 @@ |
kPauseMsg = 1, |
kResumeMsg = 2, |
kPingMsg = 3, |
+ kKillMsg = 4, |
kImmediateAction = 0, |
kBeforeNextEventAction = 1, |
kAsEventAction = 2 |
}; |
- void HandleLibMessage(const Array& message); |
+ // A result of false indicates that the isolate should terminate the |
+ // processing of further events. |
+ bool HandleLibMessage(const Array& message); |
siva
2014/12/13 00:24:05
Not for this CL but it might be more readable to h
Ivan Posva
2014/12/13 00:36:47
Seems like a plan.
|
+ |
bool ProcessUnhandledException(const Object& message, const Error& result); |
RawFunction* ResolveCallbackFunction(); |
Isolate* isolate_; |
@@ -135,20 +139,19 @@ |
// Isolate library OOB messages are fixed sized arrays which have the |
// following format: |
// [ OOB dispatch, Isolate library dispatch, <message specific data> ] |
-void IsolateMessageHandler::HandleLibMessage(const Array& message) { |
- if (message.Length() < 2) return; |
+bool IsolateMessageHandler::HandleLibMessage(const Array& message) { |
+ if (message.Length() < 2) return true; |
const Object& type = Object::Handle(I, message.At(1)); |
- if (!type.IsSmi()) return; |
+ if (!type.IsSmi()) return true; |
const Smi& msg_type = Smi::Cast(type); |
switch (msg_type.Value()) { |
case kPauseMsg: { |
// [ OOB, kPauseMsg, pause capability, resume capability ] |
- if (message.Length() != 4) return; |
+ if (message.Length() != 4) return true; |
Object& obj = Object::Handle(I, message.At(2)); |
- if (!obj.IsCapability()) return; |
- if (!I->VerifyPauseCapability(Capability::Cast(obj))) return; |
+ if (!I->VerifyPauseCapability(obj)) return true; |
obj = message.At(3); |
- if (!obj.IsCapability()) return; |
+ if (!obj.IsCapability()) return true; |
if (I->AddResumeCapability(Capability::Cast(obj))) { |
increment_paused(); |
} |
@@ -156,34 +159,35 @@ |
} |
case kResumeMsg: { |
// [ OOB, kResumeMsg, pause capability, resume capability ] |
- if (message.Length() != 4) return; |
+ if (message.Length() != 4) return true; |
Object& obj = Object::Handle(I, message.At(2)); |
- if (!obj.IsCapability()) return; |
- if (!I->VerifyPauseCapability(Capability::Cast(obj))) return; |
+ if (!I->VerifyPauseCapability(obj)) return true; |
obj = message.At(3); |
- if (!obj.IsCapability()) return; |
+ if (!obj.IsCapability()) return true; |
if (I->RemoveResumeCapability(Capability::Cast(obj))) { |
decrement_paused(); |
} |
break; |
} |
case kPingMsg: { |
- // [ OOB, kPingMsg, responsePort, pingType ] |
- if (message.Length() != 4) return; |
+ // [ OOB, kPingMsg, responsePort, priority ] |
+ if (message.Length() != 4) return true; |
const Object& obj2 = Object::Handle(I, message.At(2)); |
- if (!obj2.IsSendPort()) return; |
+ if (!obj2.IsSendPort()) return true; |
const SendPort& send_port = SendPort::Cast(obj2); |
const Object& obj3 = Object::Handle(I, message.At(3)); |
- if (!obj3.IsSmi()) return; |
- const intptr_t ping_type = Smi::Cast(obj3).Value(); |
- if (ping_type == kImmediateAction) { |
+ if (!obj3.IsSmi()) return true; |
+ const intptr_t priority = Smi::Cast(obj3).Value(); |
+ if (priority == kImmediateAction) { |
uint8_t* data = NULL; |
intptr_t len = 0; |
SerializeObject(Object::null_instance(), &data, &len); |
PortMap::PostMessage(new Message(send_port.Id(), |
data, len, |
Message::kNormalPriority)); |
- } else if (ping_type == kBeforeNextEventAction) { |
+ } else { |
+ ASSERT((priority == kBeforeNextEventAction) || |
+ (priority == kAsEventAction)); |
// Update the message so that it will be handled immediately when it |
// is picked up from the message queue the next time. |
message.SetAt( |
@@ -195,8 +199,23 @@ |
this->PostMessage(new Message(Message::kIllegalPort, |
data, len, |
Message::kNormalPriority), |
- true /* at_head */); |
- } else if (ping_type == kAsEventAction) { |
+ priority == kBeforeNextEventAction /* at_head */); |
+ } |
+ break; |
+ } |
+ case kKillMsg: { |
+ // [ OOB, kKillMsg, terminate capability, priority ] |
+ if (message.Length() != 4) return true; |
+ Object& obj = Object::Handle(I, message.At(3)); |
+ if (!obj.IsSmi()) return true; |
+ const intptr_t priority = Smi::Cast(obj).Value(); |
+ if (priority == kImmediateAction) { |
+ obj = message.At(2); |
+ // Signal that the isolate should stop execution. |
+ return !I->VerifyTerminateCapability(obj); |
+ } else { |
+ ASSERT((priority == kBeforeNextEventAction) || |
+ (priority == kAsEventAction)); |
// Update the message so that it will be handled immediately when it |
// is picked up from the message queue the next time. |
message.SetAt( |
@@ -207,7 +226,8 @@ |
SerializeObject(message, &data, &len); |
this->PostMessage(new Message(Message::kIllegalPort, |
data, len, |
- Message::kNormalPriority)); |
+ Message::kNormalPriority), |
+ priority == kBeforeNextEventAction /* at_head */); |
} |
break; |
} |
@@ -218,6 +238,7 @@ |
break; |
#endif // defined(DEBUG) |
} |
+ return true; |
} |
@@ -303,7 +324,7 @@ |
break; |
} |
case Message::kIsolateLibOOBMsg: { |
- HandleLibMessage(oob_msg); |
+ success = HandleLibMessage(oob_msg); |
break; |
} |
#if defined(DEBUG) |
@@ -327,7 +348,7 @@ |
const Object& oob_tag = Object::Handle(I, msg_arr.At(0)); |
if (oob_tag.IsSmi() && |
(Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { |
- HandleLibMessage(Array::Cast(msg_arr)); |
+ success = HandleLibMessage(Array::Cast(msg_arr)); |
} |
} |
} |
@@ -821,11 +842,20 @@ |
} |
-bool Isolate::VerifyPauseCapability(const Capability& capability) const { |
- return !capability.IsNull() && (pause_capability() == capability.Id()); |
+bool Isolate::VerifyPauseCapability(const Object& capability) const { |
+ return !capability.IsNull() && |
+ capability.IsCapability() && |
+ (pause_capability() == Capability::Cast(capability).Id()); |
} |
+bool Isolate::VerifyTerminateCapability(const Object& capability) const { |
+ return !capability.IsNull() && |
+ capability.IsCapability() && |
+ (terminate_capability() == Capability::Cast(capability).Id()); |
+} |
+ |
+ |
bool Isolate::AddResumeCapability(const Capability& capability) { |
// Ensure a limit for the number of resume capabilities remembered. |
static const intptr_t kMaxResumeCapabilities = kSmiMax / (6*kWordSize); |
@@ -974,7 +1004,7 @@ |
HandleScope handle_scope(isolate); |
Error& error = Error::Handle(); |
error = isolate->object_store()->sticky_error(); |
- if (!error.IsNull()) { |
+ if (!error.IsNull() && !error.IsUnwindError()) { |
OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); |
} |
Dart::RunShutdownCallback(); |