OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/message_handler.h" | 5 #include "vm/message_handler.h" |
6 | 6 |
7 #include "vm/dart.h" | 7 #include "vm/dart.h" |
8 #include "vm/lockers.h" | 8 #include "vm/lockers.h" |
9 #include "vm/object.h" | 9 #include "vm/object.h" |
10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 MessageHandler::MessageHandler() | 57 MessageHandler::MessageHandler() |
58 : queue_(new MessageQueue()), | 58 : queue_(new MessageQueue()), |
59 oob_queue_(new MessageQueue()), | 59 oob_queue_(new MessageQueue()), |
60 oob_message_handling_allowed_(true), | 60 oob_message_handling_allowed_(true), |
61 live_ports_(0), | 61 live_ports_(0), |
62 paused_(0), | 62 paused_(0), |
63 should_pause_on_start_(false), | 63 should_pause_on_start_(false), |
64 should_pause_on_exit_(false), | 64 should_pause_on_exit_(false), |
65 is_paused_on_start_(false), | 65 is_paused_on_start_(false), |
66 is_paused_on_exit_(false), | 66 is_paused_on_exit_(false), |
| 67 delete_me_(false), |
67 paused_timestamp_(-1), | 68 paused_timestamp_(-1), |
68 pool_(NULL), | 69 pool_(NULL), |
69 task_(NULL), | 70 task_(NULL), |
70 start_callback_(NULL), | 71 start_callback_(NULL), |
71 end_callback_(NULL), | 72 end_callback_(NULL), |
72 callback_data_(0) { | 73 callback_data_(0) { |
73 ASSERT(queue_ != NULL); | 74 ASSERT(queue_ != NULL); |
74 ASSERT(oob_queue_ != NULL); | 75 ASSERT(oob_queue_ != NULL); |
75 } | 76 } |
76 | 77 |
77 | 78 |
78 MessageHandler::~MessageHandler() { | 79 MessageHandler::~MessageHandler() { |
79 delete queue_; | 80 delete queue_; |
80 delete oob_queue_; | 81 delete oob_queue_; |
| 82 queue_ = NULL; |
| 83 oob_queue_ = NULL; |
| 84 pool_ = NULL; |
| 85 task_ = NULL; |
81 } | 86 } |
82 | 87 |
83 | 88 |
84 const char* MessageHandler::name() const { | 89 const char* MessageHandler::name() const { |
85 return "<unnamed>"; | 90 return "<unnamed>"; |
86 } | 91 } |
87 | 92 |
88 | 93 |
89 #if defined(DEBUG) | 94 #if defined(DEBUG) |
90 void MessageHandler::CheckAccess() { | 95 void MessageHandler::CheckAccess() { |
(...skipping 12 matching lines...) Expand all Loading... |
103 EndCallback end_callback, | 108 EndCallback end_callback, |
104 CallbackData data) { | 109 CallbackData data) { |
105 bool task_running; | 110 bool task_running; |
106 MonitorLocker ml(&monitor_); | 111 MonitorLocker ml(&monitor_); |
107 if (FLAG_trace_isolates) { | 112 if (FLAG_trace_isolates) { |
108 OS::Print("[+] Starting message handler:\n" | 113 OS::Print("[+] Starting message handler:\n" |
109 "\thandler: %s\n", | 114 "\thandler: %s\n", |
110 name()); | 115 name()); |
111 } | 116 } |
112 ASSERT(pool_ == NULL); | 117 ASSERT(pool_ == NULL); |
| 118 ASSERT(!delete_me_); |
113 pool_ = pool; | 119 pool_ = pool; |
114 start_callback_ = start_callback; | 120 start_callback_ = start_callback; |
115 end_callback_ = end_callback; | 121 end_callback_ = end_callback; |
116 callback_data_ = data; | 122 callback_data_ = data; |
117 task_ = new MessageHandlerTask(this); | 123 task_ = new MessageHandlerTask(this); |
118 task_running = pool_->Run(task_); | 124 task_running = pool_->Run(task_); |
119 ASSERT(task_running); | 125 ASSERT(task_running); |
120 } | 126 } |
121 | 127 |
122 | 128 |
(...skipping 18 matching lines...) Expand all Loading... |
141 | 147 |
142 saved_priority = message->priority(); | 148 saved_priority = message->priority(); |
143 if (message->IsOOB()) { | 149 if (message->IsOOB()) { |
144 oob_queue_->Enqueue(message, before_events); | 150 oob_queue_->Enqueue(message, before_events); |
145 } else { | 151 } else { |
146 queue_->Enqueue(message, before_events); | 152 queue_->Enqueue(message, before_events); |
147 } | 153 } |
148 message = NULL; // Do not access message. May have been deleted. | 154 message = NULL; // Do not access message. May have been deleted. |
149 | 155 |
150 if ((pool_ != NULL) && (task_ == NULL)) { | 156 if ((pool_ != NULL) && (task_ == NULL)) { |
| 157 ASSERT(!delete_me_); |
151 task_ = new MessageHandlerTask(this); | 158 task_ = new MessageHandlerTask(this); |
152 task_running = pool_->Run(task_); | 159 task_running = pool_->Run(task_); |
153 } | 160 } |
154 } | 161 } |
155 ASSERT(task_running); | 162 ASSERT(task_running); |
156 | 163 |
157 // Invoke any custom message notification. | 164 // Invoke any custom message notification. |
158 MessageNotify(saved_priority); | 165 MessageNotify(saved_priority); |
159 } | 166 } |
160 | 167 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 } | 251 } |
245 return max_status; | 252 return max_status; |
246 } | 253 } |
247 | 254 |
248 | 255 |
249 MessageHandler::MessageStatus MessageHandler::HandleNextMessage() { | 256 MessageHandler::MessageStatus MessageHandler::HandleNextMessage() { |
250 // We can only call HandleNextMessage when this handler is not | 257 // We can only call HandleNextMessage when this handler is not |
251 // assigned to a thread pool. | 258 // assigned to a thread pool. |
252 MonitorLocker ml(&monitor_); | 259 MonitorLocker ml(&monitor_); |
253 ASSERT(pool_ == NULL); | 260 ASSERT(pool_ == NULL); |
| 261 ASSERT(!delete_me_); |
254 #if defined(DEBUG) | 262 #if defined(DEBUG) |
255 CheckAccess(); | 263 CheckAccess(); |
256 #endif | 264 #endif |
257 return HandleMessages(&ml, true, false); | 265 return HandleMessages(&ml, true, false); |
258 } | 266 } |
259 | 267 |
260 | 268 |
261 MessageHandler::MessageStatus MessageHandler::HandleAllMessages() { | 269 MessageHandler::MessageStatus MessageHandler::HandleAllMessages() { |
262 // We can only call HandleAllMessages when this handler is not | 270 // We can only call HandleAllMessages when this handler is not |
263 // assigned to a thread pool. | 271 // assigned to a thread pool. |
264 MonitorLocker ml(&monitor_); | 272 MonitorLocker ml(&monitor_); |
265 ASSERT(pool_ == NULL); | 273 ASSERT(pool_ == NULL); |
| 274 ASSERT(!delete_me_); |
266 #if defined(DEBUG) | 275 #if defined(DEBUG) |
267 CheckAccess(); | 276 CheckAccess(); |
268 #endif | 277 #endif |
269 return HandleMessages(&ml, true, true); | 278 return HandleMessages(&ml, true, true); |
270 } | 279 } |
271 | 280 |
272 | 281 |
273 MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() { | 282 MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() { |
274 if (!oob_message_handling_allowed_) { | 283 if (!oob_message_handling_allowed_) { |
275 return kOK; | 284 return kOK; |
276 } | 285 } |
277 MonitorLocker ml(&monitor_); | 286 MonitorLocker ml(&monitor_); |
| 287 ASSERT(!delete_me_); |
278 #if defined(DEBUG) | 288 #if defined(DEBUG) |
279 CheckAccess(); | 289 CheckAccess(); |
280 #endif | 290 #endif |
281 return HandleMessages(&ml, false, false); | 291 return HandleMessages(&ml, false, false); |
282 } | 292 } |
283 | 293 |
284 | 294 |
285 bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const { | 295 bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const { |
286 Isolate* owning_isolate = isolate(); | 296 Isolate* owning_isolate = isolate(); |
287 if (owning_isolate == NULL) { | 297 if (owning_isolate == NULL) { |
(...skipping 21 matching lines...) Expand all Loading... |
309 bool MessageHandler::HasOOBMessages() { | 319 bool MessageHandler::HasOOBMessages() { |
310 MonitorLocker ml(&monitor_); | 320 MonitorLocker ml(&monitor_); |
311 return !oob_queue_->IsEmpty(); | 321 return !oob_queue_->IsEmpty(); |
312 } | 322 } |
313 | 323 |
314 | 324 |
315 void MessageHandler::TaskCallback() { | 325 void MessageHandler::TaskCallback() { |
316 ASSERT(Isolate::Current() == NULL); | 326 ASSERT(Isolate::Current() == NULL); |
317 MessageStatus status = kOK; | 327 MessageStatus status = kOK; |
318 bool run_end_callback = false; | 328 bool run_end_callback = false; |
| 329 bool delete_me = false; |
319 { | 330 { |
320 // We will occasionally release and reacquire this monitor in this | 331 // We will occasionally release and reacquire this monitor in this |
321 // function. Whenever we reacquire the monitor we *must* process | 332 // function. Whenever we reacquire the monitor we *must* process |
322 // all pending OOB messages, or we may miss a request for vm | 333 // all pending OOB messages, or we may miss a request for vm |
323 // shutdown. | 334 // shutdown. |
324 MonitorLocker ml(&monitor_); | 335 MonitorLocker ml(&monitor_); |
325 if (ShouldPauseOnStart(kOK)) { | 336 if (ShouldPauseOnStart(kOK)) { |
326 if (!is_paused_on_start()) { | 337 if (!is_paused_on_start()) { |
327 PausedOnStartLocked(&ml, true); | 338 PausedOnStartLocked(&ml, true); |
328 } | 339 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 "\terror: %s\n", | 399 "\terror: %s\n", |
389 MessageStatusString(status), name(), error.ToCString()); | 400 MessageStatusString(status), name(), error.ToCString()); |
390 } else { | 401 } else { |
391 OS::Print("[-] Stopping message handler (%s):\n" | 402 OS::Print("[-] Stopping message handler (%s):\n" |
392 "\thandler: %s\n", | 403 "\thandler: %s\n", |
393 MessageStatusString(status), name()); | 404 MessageStatusString(status), name()); |
394 } | 405 } |
395 } | 406 } |
396 pool_ = NULL; | 407 pool_ = NULL; |
397 run_end_callback = true; | 408 run_end_callback = true; |
| 409 delete_me = delete_me_; |
398 } | 410 } |
399 | 411 |
400 // Clear the task_ last. This allows other tasks to potentially start | 412 // Clear the task_ last. This allows other tasks to potentially start |
401 // for this message handler. | 413 // for this message handler. |
402 ASSERT(oob_queue_->IsEmpty()); | 414 ASSERT(oob_queue_->IsEmpty()); |
403 task_ = NULL; | 415 task_ = NULL; |
404 } | 416 } |
| 417 |
| 418 // Message handlers either use delete_me or end_callback but not both. |
| 419 ASSERT(!delete_me || end_callback_ == NULL); |
| 420 |
405 if (run_end_callback && end_callback_ != NULL) { | 421 if (run_end_callback && end_callback_ != NULL) { |
406 end_callback_(callback_data_); | 422 end_callback_(callback_data_); |
407 // The handler may have been deleted after this point. | 423 // The handler may have been deleted after this point. |
408 } | 424 } |
| 425 if (delete_me) { |
| 426 delete this; |
| 427 } |
409 } | 428 } |
410 | 429 |
411 | 430 |
412 void MessageHandler::ClosePort(Dart_Port port) { | 431 void MessageHandler::ClosePort(Dart_Port port) { |
413 MonitorLocker ml(&monitor_); | 432 MonitorLocker ml(&monitor_); |
414 if (FLAG_trace_isolates) { | 433 if (FLAG_trace_isolates) { |
415 OS::Print("[-] Closing port:\n" | 434 OS::Print("[-] Closing port:\n" |
416 "\thandler: %s\n" | 435 "\thandler: %s\n" |
417 "\tport: %" Pd64 "\n" | 436 "\tport: %" Pd64 "\n" |
418 "\tports: live(%" Pd ")\n", | 437 "\tports: live(%" Pd ")\n", |
419 name(), port, live_ports_); | 438 name(), port, live_ports_); |
420 } | 439 } |
421 } | 440 } |
422 | 441 |
423 | 442 |
424 void MessageHandler::CloseAllPorts() { | 443 void MessageHandler::CloseAllPorts() { |
425 MonitorLocker ml(&monitor_); | 444 MonitorLocker ml(&monitor_); |
426 if (FLAG_trace_isolates) { | 445 if (FLAG_trace_isolates) { |
427 OS::Print("[-] Closing all ports:\n" | 446 OS::Print("[-] Closing all ports:\n" |
428 "\thandler: %s\n", | 447 "\thandler: %s\n", |
429 name()); | 448 name()); |
430 } | 449 } |
431 queue_->Clear(); | 450 queue_->Clear(); |
432 oob_queue_->Clear(); | 451 oob_queue_->Clear(); |
433 } | 452 } |
434 | 453 |
435 | 454 |
| 455 void MessageHandler::RequestDeletion() { |
| 456 ASSERT(OwnedByPortMap()); |
| 457 { |
| 458 MonitorLocker ml(&monitor_); |
| 459 if (task_ != NULL) { |
| 460 // This message handler currently has a task running on the thread pool. |
| 461 delete_me_ = true; |
| 462 return; |
| 463 } |
| 464 } |
| 465 |
| 466 // This message handler has no current task. Delete it. |
| 467 delete this; |
| 468 } |
| 469 |
| 470 |
436 void MessageHandler::increment_live_ports() { | 471 void MessageHandler::increment_live_ports() { |
437 MonitorLocker ml(&monitor_); | 472 MonitorLocker ml(&monitor_); |
438 #if defined(DEBUG) | 473 #if defined(DEBUG) |
439 CheckAccess(); | 474 CheckAccess(); |
440 #endif | 475 #endif |
441 live_ports_++; | 476 live_ports_++; |
442 } | 477 } |
443 | 478 |
444 | 479 |
445 void MessageHandler::decrement_live_ports() { | 480 void MessageHandler::decrement_live_ports() { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 handler_->oob_message_handling_allowed_ = false; | 565 handler_->oob_message_handling_allowed_ = false; |
531 } | 566 } |
532 | 567 |
533 | 568 |
534 MessageHandler::AcquiredQueues::~AcquiredQueues() { | 569 MessageHandler::AcquiredQueues::~AcquiredQueues() { |
535 ASSERT(handler_ != NULL); | 570 ASSERT(handler_ != NULL); |
536 handler_->oob_message_handling_allowed_ = true; | 571 handler_->oob_message_handling_allowed_ = true; |
537 } | 572 } |
538 | 573 |
539 } // namespace dart | 574 } // namespace dart |
OLD | NEW |