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