| 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 return "Illegal"; | 49 return "Illegal"; |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 | 52 |
| 53 MessageHandler::MessageHandler() | 53 MessageHandler::MessageHandler() |
| 54 : queue_(new MessageQueue()), | 54 : queue_(new MessageQueue()), |
| 55 oob_queue_(new MessageQueue()), | 55 oob_queue_(new MessageQueue()), |
| 56 oob_message_handling_allowed_(true), | 56 oob_message_handling_allowed_(true), |
| 57 live_ports_(0), | 57 live_ports_(0), |
| 58 paused_(0), | 58 paused_(0), |
| 59 #if !defined(PRODUCT) |
| 59 should_pause_on_start_(false), | 60 should_pause_on_start_(false), |
| 60 should_pause_on_exit_(false), | 61 should_pause_on_exit_(false), |
| 61 is_paused_on_start_(false), | 62 is_paused_on_start_(false), |
| 62 is_paused_on_exit_(false), | 63 is_paused_on_exit_(false), |
| 64 paused_timestamp_(-1), |
| 65 #endif |
| 63 delete_me_(false), | 66 delete_me_(false), |
| 64 paused_timestamp_(-1), | |
| 65 pool_(NULL), | 67 pool_(NULL), |
| 66 task_(NULL), | 68 task_(NULL), |
| 67 start_callback_(NULL), | 69 start_callback_(NULL), |
| 68 end_callback_(NULL), | 70 end_callback_(NULL), |
| 69 callback_data_(0) { | 71 callback_data_(0) { |
| 70 ASSERT(queue_ != NULL); | 72 ASSERT(queue_ != NULL); |
| 71 ASSERT(oob_queue_ != NULL); | 73 ASSERT(oob_queue_ != NULL); |
| 72 } | 74 } |
| 73 | 75 |
| 74 MessageHandler::~MessageHandler() { | 76 MessageHandler::~MessageHandler() { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 return kOK; | 276 return kOK; |
| 275 } | 277 } |
| 276 MonitorLocker ml(&monitor_); | 278 MonitorLocker ml(&monitor_); |
| 277 ASSERT(!delete_me_); | 279 ASSERT(!delete_me_); |
| 278 #if defined(DEBUG) | 280 #if defined(DEBUG) |
| 279 CheckAccess(); | 281 CheckAccess(); |
| 280 #endif | 282 #endif |
| 281 return HandleMessages(&ml, false, false); | 283 return HandleMessages(&ml, false, false); |
| 282 } | 284 } |
| 283 | 285 |
| 286 #if !defined(PRODUCT) |
| 284 bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const { | 287 bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const { |
| 285 Isolate* owning_isolate = isolate(); | 288 Isolate* owning_isolate = isolate(); |
| 286 if (owning_isolate == NULL) { | 289 if (owning_isolate == NULL) { |
| 287 return false; | 290 return false; |
| 288 } | 291 } |
| 289 // If we are restarting or shutting down, we do not want to honor | 292 // If we are restarting or shutting down, we do not want to honor |
| 290 // should_pause_on_start or should_pause_on_exit. | 293 // should_pause_on_start or should_pause_on_exit. |
| 291 return (status != MessageHandler::kRestart && | 294 return (status != MessageHandler::kRestart && |
| 292 status != MessageHandler::kShutdown) && | 295 status != MessageHandler::kShutdown) && |
| 293 should_pause_on_start() && owning_isolate->is_runnable(); | 296 should_pause_on_start() && owning_isolate->is_runnable(); |
| 294 } | 297 } |
| 295 | 298 |
| 296 bool MessageHandler::ShouldPauseOnExit(MessageStatus status) const { | 299 bool MessageHandler::ShouldPauseOnExit(MessageStatus status) const { |
| 297 Isolate* owning_isolate = isolate(); | 300 Isolate* owning_isolate = isolate(); |
| 298 if (owning_isolate == NULL) { | 301 if (owning_isolate == NULL) { |
| 299 return false; | 302 return false; |
| 300 } | 303 } |
| 301 return (status != MessageHandler::kRestart && | 304 return (status != MessageHandler::kRestart && |
| 302 status != MessageHandler::kShutdown) && | 305 status != MessageHandler::kShutdown) && |
| 303 should_pause_on_exit() && owning_isolate->is_runnable(); | 306 should_pause_on_exit() && owning_isolate->is_runnable(); |
| 304 } | 307 } |
| 308 #endif |
| 305 | 309 |
| 306 bool MessageHandler::HasOOBMessages() { | 310 bool MessageHandler::HasOOBMessages() { |
| 307 MonitorLocker ml(&monitor_); | 311 MonitorLocker ml(&monitor_); |
| 308 return !oob_queue_->IsEmpty(); | 312 return !oob_queue_->IsEmpty(); |
| 309 } | 313 } |
| 310 | 314 |
| 311 void MessageHandler::TaskCallback() { | 315 void MessageHandler::TaskCallback() { |
| 312 ASSERT(Isolate::Current() == NULL); | 316 ASSERT(Isolate::Current() == NULL); |
| 313 MessageStatus status = kOK; | 317 MessageStatus status = kOK; |
| 314 bool run_end_callback = false; | 318 bool run_end_callback = false; |
| 315 bool delete_me = false; | 319 bool delete_me = false; |
| 316 EndCallback end_callback = NULL; | 320 EndCallback end_callback = NULL; |
| 317 CallbackData callback_data = 0; | 321 CallbackData callback_data = 0; |
| 318 { | 322 { |
| 319 // We will occasionally release and reacquire this monitor in this | 323 // We will occasionally release and reacquire this monitor in this |
| 320 // function. Whenever we reacquire the monitor we *must* process | 324 // function. Whenever we reacquire the monitor we *must* process |
| 321 // all pending OOB messages, or we may miss a request for vm | 325 // all pending OOB messages, or we may miss a request for vm |
| 322 // shutdown. | 326 // shutdown. |
| 323 MonitorLocker ml(&monitor_); | 327 MonitorLocker ml(&monitor_); |
| 328 #if !defined(PRODUCT) |
| 324 if (ShouldPauseOnStart(kOK)) { | 329 if (ShouldPauseOnStart(kOK)) { |
| 325 if (!is_paused_on_start()) { | 330 if (!is_paused_on_start()) { |
| 326 PausedOnStartLocked(&ml, true); | 331 PausedOnStartLocked(&ml, true); |
| 327 } | 332 } |
| 328 // More messages may have come in before we (re)acquired the monitor. | 333 // More messages may have come in before we (re)acquired the monitor. |
| 329 status = HandleMessages(&ml, false, false); | 334 status = HandleMessages(&ml, false, false); |
| 330 if (ShouldPauseOnStart(status)) { | 335 if (ShouldPauseOnStart(status)) { |
| 331 // Still paused. | 336 // Still paused. |
| 332 ASSERT(oob_queue_->IsEmpty()); | 337 ASSERT(oob_queue_->IsEmpty()); |
| 333 task_ = NULL; // No task in queue. | 338 task_ = NULL; // No task in queue. |
| 334 return; | 339 return; |
| 335 } else { | 340 } else { |
| 336 PausedOnStartLocked(&ml, false); | 341 PausedOnStartLocked(&ml, false); |
| 337 } | 342 } |
| 338 } | 343 } |
| 344 #endif |
| 339 | 345 |
| 340 if (status == kOK) { | 346 if (status == kOK) { |
| 341 if (start_callback_) { | 347 if (start_callback_) { |
| 342 // Initialize the message handler by running its start function, | 348 // Initialize the message handler by running its start function, |
| 343 // if we have one. For an isolate, this will run the isolate's | 349 // if we have one. For an isolate, this will run the isolate's |
| 344 // main() function. | 350 // main() function. |
| 345 // | 351 // |
| 346 // Release the monitor_ temporarily while we call the start callback. | 352 // Release the monitor_ temporarily while we call the start callback. |
| 347 ml.Exit(); | 353 ml.Exit(); |
| 348 status = start_callback_(callback_data_); | 354 status = start_callback_(callback_data_); |
| 349 ASSERT(Isolate::Current() == NULL); | 355 ASSERT(Isolate::Current() == NULL); |
| 350 start_callback_ = NULL; | 356 start_callback_ = NULL; |
| 351 ml.Enter(); | 357 ml.Enter(); |
| 352 } | 358 } |
| 353 | 359 |
| 354 // Handle any pending messages for this message handler. | 360 // Handle any pending messages for this message handler. |
| 355 if (status != kShutdown) { | 361 if (status != kShutdown) { |
| 356 status = HandleMessages(&ml, (status == kOK), true); | 362 status = HandleMessages(&ml, (status == kOK), true); |
| 357 } | 363 } |
| 358 } | 364 } |
| 359 | 365 |
| 360 // The isolate exits when it encounters an error or when it no | 366 // The isolate exits when it encounters an error or when it no |
| 361 // longer has live ports. | 367 // longer has live ports. |
| 362 if (status != kOK || !HasLivePorts()) { | 368 if (status != kOK || !HasLivePorts()) { |
| 369 #if !defined(PRODUCT) |
| 363 if (ShouldPauseOnExit(status)) { | 370 if (ShouldPauseOnExit(status)) { |
| 364 if (!is_paused_on_exit()) { | 371 if (!is_paused_on_exit()) { |
| 365 if (FLAG_trace_service_pause_events) { | 372 if (FLAG_trace_service_pause_events) { |
| 366 OS::PrintErr( | 373 OS::PrintErr( |
| 367 "Isolate %s paused before exiting. " | 374 "Isolate %s paused before exiting. " |
| 368 "Use the Observatory to release it.\n", | 375 "Use the Observatory to release it.\n", |
| 369 name()); | 376 name()); |
| 370 } | 377 } |
| 371 PausedOnExitLocked(&ml, true); | 378 PausedOnExitLocked(&ml, true); |
| 372 // More messages may have come in while we released the monitor. | 379 // More messages may have come in while we released the monitor. |
| 373 status = HandleMessages(&ml, false, false); | 380 status = HandleMessages(&ml, false, false); |
| 374 } | 381 } |
| 375 if (ShouldPauseOnExit(status)) { | 382 if (ShouldPauseOnExit(status)) { |
| 376 // Still paused. | 383 // Still paused. |
| 377 ASSERT(oob_queue_->IsEmpty()); | 384 ASSERT(oob_queue_->IsEmpty()); |
| 378 task_ = NULL; // No task in queue. | 385 task_ = NULL; // No task in queue. |
| 379 return; | 386 return; |
| 380 } else { | 387 } else { |
| 381 PausedOnExitLocked(&ml, false); | 388 PausedOnExitLocked(&ml, false); |
| 382 } | 389 } |
| 383 } | 390 } |
| 391 #endif // !defined(PRODUCT) |
| 384 if (FLAG_trace_isolates) { | 392 if (FLAG_trace_isolates) { |
| 385 if (status != kOK && thread() != NULL) { | 393 if (status != kOK && thread() != NULL) { |
| 386 const Error& error = Error::Handle(thread()->sticky_error()); | 394 const Error& error = Error::Handle(thread()->sticky_error()); |
| 387 OS::Print( | 395 OS::Print( |
| 388 "[-] Stopping message handler (%s):\n" | 396 "[-] Stopping message handler (%s):\n" |
| 389 "\thandler: %s\n" | 397 "\thandler: %s\n" |
| 390 "\terror: %s\n", | 398 "\terror: %s\n", |
| 391 MessageStatusString(status), name(), error.ToCString()); | 399 MessageStatusString(status), name(), error.ToCString()); |
| 392 } else { | 400 } else { |
| 393 OS::Print( | 401 OS::Print( |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 } | 483 } |
| 476 | 484 |
| 477 void MessageHandler::decrement_live_ports() { | 485 void MessageHandler::decrement_live_ports() { |
| 478 MonitorLocker ml(&monitor_); | 486 MonitorLocker ml(&monitor_); |
| 479 #if defined(DEBUG) | 487 #if defined(DEBUG) |
| 480 CheckAccess(); | 488 CheckAccess(); |
| 481 #endif | 489 #endif |
| 482 live_ports_--; | 490 live_ports_--; |
| 483 } | 491 } |
| 484 | 492 |
| 493 #if !defined(PRODUCT) |
| 494 void MessageHandler::DebugDump() { |
| 495 PortMap::DebugDumpForMessageHandler(this); |
| 496 } |
| 497 |
| 485 void MessageHandler::PausedOnStart(bool paused) { | 498 void MessageHandler::PausedOnStart(bool paused) { |
| 486 MonitorLocker ml(&monitor_); | 499 MonitorLocker ml(&monitor_); |
| 487 PausedOnStartLocked(&ml, paused); | 500 PausedOnStartLocked(&ml, paused); |
| 488 } | 501 } |
| 489 | 502 |
| 490 void MessageHandler::DebugDump() { | |
| 491 PortMap::DebugDumpForMessageHandler(this); | |
| 492 } | |
| 493 | |
| 494 void MessageHandler::PausedOnStartLocked(MonitorLocker* ml, bool paused) { | 503 void MessageHandler::PausedOnStartLocked(MonitorLocker* ml, bool paused) { |
| 495 if (paused) { | 504 if (paused) { |
| 496 ASSERT(!is_paused_on_start_); | 505 ASSERT(!is_paused_on_start_); |
| 497 is_paused_on_start_ = true; | 506 is_paused_on_start_ = true; |
| 498 paused_timestamp_ = OS::GetCurrentTimeMillis(); | 507 paused_timestamp_ = OS::GetCurrentTimeMillis(); |
| 499 } else { | 508 } else { |
| 500 ASSERT(is_paused_on_start_); | 509 ASSERT(is_paused_on_start_); |
| 501 is_paused_on_start_ = false; | 510 is_paused_on_start_ = false; |
| 502 paused_timestamp_ = -1; | 511 paused_timestamp_ = -1; |
| 503 } | 512 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 NotifyPauseOnExit(); | 551 NotifyPauseOnExit(); |
| 543 ml->Enter(); | 552 ml->Enter(); |
| 544 } else { | 553 } else { |
| 545 // Resumed. Clear the resume request of the owning isolate. | 554 // Resumed. Clear the resume request of the owning isolate. |
| 546 Isolate* owning_isolate = isolate(); | 555 Isolate* owning_isolate = isolate(); |
| 547 if (owning_isolate != NULL) { | 556 if (owning_isolate != NULL) { |
| 548 owning_isolate->GetAndClearResumeRequest(); | 557 owning_isolate->GetAndClearResumeRequest(); |
| 549 } | 558 } |
| 550 } | 559 } |
| 551 } | 560 } |
| 561 #endif // !defined(PRODUCT) |
| 552 | 562 |
| 553 MessageHandler::AcquiredQueues::AcquiredQueues(MessageHandler* handler) | 563 MessageHandler::AcquiredQueues::AcquiredQueues(MessageHandler* handler) |
| 554 : handler_(handler), ml_(&handler->monitor_) { | 564 : handler_(handler), ml_(&handler->monitor_) { |
| 555 ASSERT(handler != NULL); | 565 ASSERT(handler != NULL); |
| 556 handler_->oob_message_handling_allowed_ = false; | 566 handler_->oob_message_handling_allowed_ = false; |
| 557 } | 567 } |
| 558 | 568 |
| 559 MessageHandler::AcquiredQueues::~AcquiredQueues() { | 569 MessageHandler::AcquiredQueues::~AcquiredQueues() { |
| 560 ASSERT(handler_ != NULL); | 570 ASSERT(handler_ != NULL); |
| 561 handler_->oob_message_handling_allowed_ = true; | 571 handler_->oob_message_handling_allowed_ = true; |
| 562 } | 572 } |
| 563 | 573 |
| 564 } // namespace dart | 574 } // namespace dart |
| OLD | NEW |