Index: runtime/vm/isolate.cc |
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc |
index 195623b9b709483661e9a2fd91af3d2fdf544612..ed99e6b9c33d4f6fc04633ed04c1d074a342b5d9 100644 |
--- a/runtime/vm/isolate.cc |
+++ b/runtime/vm/isolate.cc |
@@ -156,7 +156,6 @@ class IsolateMessageHandler : public MessageHandler { |
bool IsCurrentIsolate() const; |
virtual Isolate* isolate() const { return isolate_; } |
- private: |
// Keep both these enums in sync with isolate_patch.dart. |
// The different Isolate API message types. |
enum { |
@@ -177,6 +176,7 @@ class IsolateMessageHandler : public MessageHandler { |
kAsEventAction = 2 |
}; |
+ private: |
// A result of false indicates that the isolate should terminate the |
// processing of further events. |
bool HandleLibMessage(const Array& message); |
@@ -1121,7 +1121,9 @@ void Isolate::RemoveExitListener(const SendPort& listener) { |
void Isolate::NotifyExitListeners() { |
const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
this, this->object_store()->exit_listeners()); |
- if (listeners.IsNull()) return; |
+ if (listeners.IsNull()) { |
+ return; |
+ } |
SendPort& listener = SendPort::Handle(this); |
Instance& response = Instance::Handle(this); |
@@ -1327,8 +1329,7 @@ static void ShutdownIsolate(uword parameter) { |
void Isolate::Run() { |
- message_handler()->Run(Dart::thread_pool(), |
- RunIsolate, |
+ message_handler()->Run(RunIsolate, |
ShutdownIsolate, |
reinterpret_cast<uword>(this)); |
} |
@@ -1470,7 +1471,9 @@ void Isolate::Shutdown() { |
timer_list_.ReportTimers(); |
// Write out the coverage data if collection has been enabled. |
- CodeCoverage::Write(this); |
+ if (this != Dart::vm_isolate()) { |
+ CodeCoverage::Write(this); |
+ } |
// Finalize any weak persistent handles with a non-null referent. |
FinalizeWeakPersistentHandlesVisitor visitor; |
@@ -1896,6 +1899,54 @@ T* Isolate::AllocateReusableHandle() { |
} |
+class IsolateKillerVisitor : public IsolateVisitor { |
+ public: |
+ explicit IsolateKillerVisitor(const Array& msg) |
+ : IsolateVisitor(), msg_(Array::Handle(msg.raw())) { |
+ ASSERT(msg_.Length() == 4); |
+ msg_.SetAt(0, Smi::Handle(Smi::New(Message::kIsolateLibOOBMsg))); |
+ msg_.SetAt(1, Smi::Handle(Smi::New(IsolateMessageHandler::kKillMsg))); |
+ msg_.SetAt(3, Smi::Handle(Smi::New( |
+ IsolateMessageHandler::kBeforeNextEventAction))); |
turnidge
2015/06/30 22:15:46
We discusssed offline that it should be possible t
zra
2015/07/20 22:23:38
Acknowledged.
|
+ } |
+ |
+ void VisitIsolate(Isolate* isolate) { |
+ ASSERT(isolate != NULL); |
+ if ((isolate == Isolate::Current()) || |
+ ServiceIsolate::IsServiceIsolate(isolate) || |
+ (isolate == Dart::vm_isolate())) { |
+ return; |
+ } |
+ SendKillMessageTo(isolate); |
+ } |
+ |
+ private: |
+ void SendKillMessageTo(Isolate* isolate) { |
+ // Set the capability field of the kill message with the right capability |
+ // for the isolate we are sending the message to. |
+ msg_.SetAt(2, Capability::Handle( |
+ Capability::New(isolate->terminate_capability()))); |
+ |
+ uint8_t* data = NULL; |
+ MessageWriter writer(&data, &allocator, false); |
+ writer.WriteMessage(msg_); |
+ |
+ PortMap::PostMessage(new Message(isolate->main_port(), |
+ data, writer.BytesWritten(), |
+ Message::kOOBPriority)); |
+ } |
+ |
+ Array& msg_; |
+}; |
+ |
+ |
+void Isolate::KillAllIsolates(Isolate* isolate) { |
turnidge
2015/06/30 22:15:46
Will the "isolate" param always be the current iso
zra
2015/07/20 22:23:38
No. It should always be the service isolate. I've
|
+ const Array& msg = Array::Handle(isolate, Array::New(4)); |
+ IsolateKillerVisitor visitor(msg); |
+ VisitIsolates(&visitor); |
+} |
+ |
+ |
static RawInstance* DeserializeObject(Isolate* isolate, |
Zone* zone, |
uint8_t* obj_data, |