Index: runtime/vm/isolate.cc |
=================================================================== |
--- runtime/vm/isolate.cc (revision 3743) |
+++ runtime/vm/isolate.cc (working copy) |
@@ -14,7 +14,7 @@ |
#include "vm/debugger.h" |
#include "vm/debuginfo.h" |
#include "vm/heap.h" |
-#include "vm/message_queue.h" |
+#include "vm/message.h" |
#include "vm/object_store.h" |
#include "vm/parser.h" |
#include "vm/port.h" |
@@ -34,13 +34,61 @@ |
DECLARE_FLAG(bool, generate_gdb_symbols); |
+class IsolateMessageHandler : public MessageHandler { |
+ public: |
+ explicit IsolateMessageHandler(Isolate* isolate); |
+ ~IsolateMessageHandler(); |
+ |
+ const char* name() const; |
+ void MessageNotify(Message::Priority priority); |
+ |
+#if defined(DEBUG) |
+ // Check that it is safe to access this handler. |
+ void CheckAccess(); |
+#endif |
+ private: |
+ Isolate* isolate_; |
+}; |
+ |
+ |
+IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) |
+ : isolate_(isolate) { |
+} |
+ |
+ |
+IsolateMessageHandler::~IsolateMessageHandler() { |
+} |
+ |
+const char* IsolateMessageHandler::name() const { |
+ return isolate_->name(); |
+} |
+ |
+ |
+void IsolateMessageHandler::MessageNotify(Message::Priority priority) { |
+ if (priority >= Message::kOOBPriority) { |
+ // Handle out of band messages even if the isolate is busy. |
+ // isolate_->ScheduleInterrupts(Isolate::kMessageInterrupt); |
+ UNIMPLEMENTED(); |
+ } |
+ Dart_MessageNotifyCallback callback = isolate_->message_notify_callback(); |
+ if (callback) { |
+ // Allow the embedder to handle message notification. |
+ (*callback)(Api::CastIsolate(isolate_)); |
+ } |
+} |
+ |
+ |
+#if defined(DEBUG) |
+void IsolateMessageHandler::CheckAccess() { |
+ ASSERT(isolate_ == Isolate::Current()); |
+} |
+#endif |
+ |
+ |
Isolate::Isolate() |
: store_buffer_(), |
- message_queue_(NULL), |
message_notify_callback_(NULL), |
name_(NULL), |
- num_ports_(0), |
- live_ports_(0), |
main_port_(0), |
heap_(NULL), |
object_store_(NULL), |
@@ -72,7 +120,6 @@ |
Isolate::~Isolate() { |
delete [] name_; |
- delete message_queue_; |
delete heap_; |
delete object_store_; |
// Do not delete stack resources: top_resource_ and current_zone_. |
@@ -83,51 +130,11 @@ |
delete debugger_; |
delete mutex_; |
mutex_ = NULL; // Fail fast if interrupts are scheduled on a dead isolate. |
+ delete message_handler_; |
+ message_handler_ = NULL; // Fail fast if we send messages to a dead isolate. |
} |
-void Isolate::PostMessage(Message* message) { |
- if (FLAG_trace_isolates) { |
- const char* source_name = "<native code>"; |
- Isolate* source_isolate = Isolate::Current(); |
- if (source_isolate) { |
- source_name = source_isolate->name(); |
- } |
- OS::Print("[>] Posting message:\n" |
- "\tsource: %s\n" |
- "\treply_port: %lld\n" |
- "\tdest: %s\n" |
- "\tdest_port: %lld\n", |
- source_name, message->reply_port(), name(), message->dest_port()); |
- } |
- |
- Message::Priority priority = message->priority(); |
- message_queue()->Enqueue(message); |
- message = NULL; // Do not access message. May have been deleted. |
- |
- ASSERT(priority < Message::kOOBPriority); |
- if (priority >= Message::kOOBPriority) { |
- // Handle out of band messages even if the isolate is busy. |
- ScheduleInterrupts(Isolate::kMessageInterrupt); |
- } |
- Dart_MessageNotifyCallback callback = message_notify_callback(); |
- if (callback) { |
- // Allow the embedder to handle message notification. |
- (*callback)(Api::CastIsolate(this)); |
- } |
-} |
- |
- |
-void Isolate::ClosePort(Dart_Port port) { |
- message_queue()->Flush(port); |
-} |
- |
- |
-void Isolate::CloseAllPorts() { |
- message_queue()->FlushAll(); |
-} |
- |
- |
Isolate* Isolate::Init(const char* name_prefix) { |
Isolate* result = new Isolate(); |
ASSERT(result != NULL); |
@@ -136,10 +143,10 @@ |
// the current isolate. |
SetCurrent(result); |
- // Set up the isolate message queue. |
- MessageQueue* queue = new MessageQueue(); |
- ASSERT(queue != NULL); |
- result->set_message_queue(queue); |
+ // Setup the isolate message handler. |
+ MessageHandler* handler = new IsolateMessageHandler(result); |
+ ASSERT(handler != NULL); |
+ result->set_message_handler(handler); |
// Setup the Dart API state. |
ApiState* state = new ApiState(); |
@@ -151,13 +158,13 @@ |
// TODO(5411455): Need to figure out how to set the stack limit for the |
// main thread. |
result->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(&result)); |
- result->set_main_port(PortMap::CreatePort()); |
+ result->set_main_port(PortMap::CreatePort(result->message_handler())); |
result->BuildName(name_prefix); |
result->debugger_ = new Debugger(); |
result->debugger_->Initialize(result); |
if (FLAG_trace_isolates) { |
- if (strcmp(name_prefix, "vm-isolate") != 0) { |
+ if (name_prefix == NULL || strcmp(name_prefix, "vm-isolate") != 0) { |
OS::Print("[+] Starting isolate:\n" |
"\tisolate: %s\n", result->name()); |
} |
@@ -288,10 +295,11 @@ |
} |
// Close all the ports owned by this isolate. |
- PortMap::ClosePorts(); |
+ PortMap::ClosePorts(message_handler()); |
- delete message_queue(); |
- set_message_queue(NULL); |
+ // Fail fast if anybody tries to post any more messsages to this isolate. |
+ delete message_handler(); |
+ set_message_handler(NULL); |
// Dump all accumalated timer data for the isolate. |
timer_list_.ReportTimers(); |
@@ -353,13 +361,14 @@ |
RawObject* Isolate::StandardRunLoop() { |
ASSERT(long_jump_base() != NULL); |
ASSERT(message_notify_callback() == NULL); |
+ ASSERT(message_handler() != NULL); |
- while (live_ports() > 0) { |
+ while (message_handler()->HasLivePorts()) { |
ASSERT(this == Isolate::Current()); |
Zone zone(this); |
HandleScope handle_scope(this); |
- Message* message = message_queue()->Dequeue(0); |
+ Message* message = message_handler()->queue()->Dequeue(0); |
if (message != NULL) { |
if (message->priority() >= Message::kOOBPriority) { |
// TODO(turnidge): Out of band messages will not go through the |