| Index: runtime/vm/message_handler.cc
 | 
| diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
 | 
| index 5e5f685dd8fcfabecbee0c917de2688b3812f5b6..80cfbbf361ddef27df281114dc6782c701881648 100644
 | 
| --- a/runtime/vm/message_handler.cc
 | 
| +++ b/runtime/vm/message_handler.cc
 | 
| @@ -64,6 +64,7 @@ MessageHandler::MessageHandler()
 | 
|        should_pause_on_exit_(false),
 | 
|        is_paused_on_start_(false),
 | 
|        is_paused_on_exit_(false),
 | 
| +      delete_me_(false),
 | 
|        paused_timestamp_(-1),
 | 
|        pool_(NULL),
 | 
|        task_(NULL),
 | 
| @@ -78,6 +79,10 @@ MessageHandler::MessageHandler()
 | 
|  MessageHandler::~MessageHandler() {
 | 
|    delete queue_;
 | 
|    delete oob_queue_;
 | 
| +  queue_ = NULL;
 | 
| +  oob_queue_ = NULL;
 | 
| +  pool_ = NULL;
 | 
| +  task_ = NULL;
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -110,6 +115,7 @@ void MessageHandler::Run(ThreadPool* pool,
 | 
|                name());
 | 
|    }
 | 
|    ASSERT(pool_ == NULL);
 | 
| +  ASSERT(!delete_me_);
 | 
|    pool_ = pool;
 | 
|    start_callback_ = start_callback;
 | 
|    end_callback_ = end_callback;
 | 
| @@ -148,6 +154,7 @@ void MessageHandler::PostMessage(Message* message, bool before_events) {
 | 
|      message = NULL;  // Do not access message.  May have been deleted.
 | 
|  
 | 
|      if ((pool_ != NULL) && (task_ == NULL)) {
 | 
| +      ASSERT(!delete_me_);
 | 
|        task_ = new MessageHandlerTask(this);
 | 
|        task_running = pool_->Run(task_);
 | 
|      }
 | 
| @@ -251,6 +258,7 @@ MessageHandler::MessageStatus MessageHandler::HandleNextMessage() {
 | 
|    // assigned to a thread pool.
 | 
|    MonitorLocker ml(&monitor_);
 | 
|    ASSERT(pool_ == NULL);
 | 
| +  ASSERT(!delete_me_);
 | 
|  #if defined(DEBUG)
 | 
|    CheckAccess();
 | 
|  #endif
 | 
| @@ -263,6 +271,7 @@ MessageHandler::MessageStatus MessageHandler::HandleAllMessages() {
 | 
|    // assigned to a thread pool.
 | 
|    MonitorLocker ml(&monitor_);
 | 
|    ASSERT(pool_ == NULL);
 | 
| +  ASSERT(!delete_me_);
 | 
|  #if defined(DEBUG)
 | 
|    CheckAccess();
 | 
|  #endif
 | 
| @@ -275,6 +284,7 @@ MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() {
 | 
|      return kOK;
 | 
|    }
 | 
|    MonitorLocker ml(&monitor_);
 | 
| +  ASSERT(!delete_me_);
 | 
|  #if defined(DEBUG)
 | 
|    CheckAccess();
 | 
|  #endif
 | 
| @@ -316,6 +326,7 @@ void MessageHandler::TaskCallback() {
 | 
|    ASSERT(Isolate::Current() == NULL);
 | 
|    MessageStatus status = kOK;
 | 
|    bool run_end_callback = false;
 | 
| +  bool delete_me = false;
 | 
|    {
 | 
|      // We will occasionally release and reacquire this monitor in this
 | 
|      // function. Whenever we reacquire the monitor we *must* process
 | 
| @@ -395,6 +406,7 @@ void MessageHandler::TaskCallback() {
 | 
|        }
 | 
|        pool_ = NULL;
 | 
|        run_end_callback = true;
 | 
| +      delete_me = delete_me_;
 | 
|      }
 | 
|  
 | 
|      // Clear the task_ last.  This allows other tasks to potentially start
 | 
| @@ -402,10 +414,17 @@ void MessageHandler::TaskCallback() {
 | 
|      ASSERT(oob_queue_->IsEmpty());
 | 
|      task_ = NULL;
 | 
|    }
 | 
| +
 | 
| +  // Message handlers either use delete_me or end_callback but not both.
 | 
| +  ASSERT(!delete_me || end_callback_ == NULL);
 | 
| +
 | 
|    if (run_end_callback && end_callback_ != NULL) {
 | 
|      end_callback_(callback_data_);
 | 
|      // The handler may have been deleted after this point.
 | 
|    }
 | 
| +  if (delete_me) {
 | 
| +    delete this;
 | 
| +  }
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -433,6 +452,22 @@ void MessageHandler::CloseAllPorts() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void MessageHandler::RequestDeletion() {
 | 
| +  ASSERT(OwnedByPortMap());
 | 
| +  {
 | 
| +    MonitorLocker ml(&monitor_);
 | 
| +    if (task_ != NULL) {
 | 
| +      // This message handler currently has a task running on the thread pool.
 | 
| +      delete_me_ = true;
 | 
| +      return;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  // This message handler has no current task.  Delete it.
 | 
| +  delete this;
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void MessageHandler::increment_live_ports() {
 | 
|    MonitorLocker ml(&monitor_);
 | 
|  #if defined(DEBUG)
 | 
| 
 |