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