Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: runtime/vm/message_handler.cc

Issue 1665773004: Add necessary support functions so that embedders can implemented pause on start and exit (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/message_handler.h ('k') | runtime/vm/service.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 } 54 }
55 } 55 }
56 56
57 57
58 MessageHandler::MessageHandler() 58 MessageHandler::MessageHandler()
59 : queue_(new MessageQueue()), 59 : queue_(new MessageQueue()),
60 oob_queue_(new MessageQueue()), 60 oob_queue_(new MessageQueue()),
61 oob_message_handling_allowed_(true), 61 oob_message_handling_allowed_(true),
62 live_ports_(0), 62 live_ports_(0),
63 paused_(0), 63 paused_(0),
64 pause_on_start_(false), 64 should_pause_on_start_(false),
65 pause_on_exit_(false), 65 should_pause_on_exit_(false),
66 paused_on_start_(false), 66 is_paused_on_start_(false),
67 paused_on_exit_(false), 67 is_paused_on_exit_(false),
68 paused_timestamp_(-1), 68 paused_timestamp_(-1),
69 pool_(NULL), 69 pool_(NULL),
70 task_(NULL), 70 task_(NULL),
71 start_callback_(NULL), 71 start_callback_(NULL),
72 end_callback_(NULL), 72 end_callback_(NULL),
73 callback_data_(0) { 73 callback_data_(0) {
74 ASSERT(queue_ != NULL); 74 ASSERT(queue_ != NULL);
75 ASSERT(oob_queue_ != NULL); 75 ASSERT(oob_queue_ != NULL);
76 } 76 }
77 77
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 // assigned to a thread pool. 251 // assigned to a thread pool.
252 MonitorLocker ml(&monitor_); 252 MonitorLocker ml(&monitor_);
253 ASSERT(pool_ == NULL); 253 ASSERT(pool_ == NULL);
254 #if defined(DEBUG) 254 #if defined(DEBUG)
255 CheckAccess(); 255 CheckAccess();
256 #endif 256 #endif
257 return HandleMessages(true, false); 257 return HandleMessages(true, false);
258 } 258 }
259 259
260 260
261 MessageHandler::MessageStatus MessageHandler::HandleAllMessages() {
262 // We can only call HandleAllMessages when this handler is not
263 // assigned to a thread pool.
264 MonitorLocker ml(&monitor_);
265 ASSERT(pool_ == NULL);
266 #if defined(DEBUG)
267 CheckAccess();
268 #endif
269 return HandleMessages(true, true);
270 }
271
272
261 MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() { 273 MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() {
262 if (!oob_message_handling_allowed_) { 274 if (!oob_message_handling_allowed_) {
263 return kOK; 275 return kOK;
264 } 276 }
265 MonitorLocker ml(&monitor_); 277 MonitorLocker ml(&monitor_);
266 #if defined(DEBUG) 278 #if defined(DEBUG)
267 CheckAccess(); 279 CheckAccess();
268 #endif 280 #endif
269 return HandleMessages(false, false); 281 return HandleMessages(false, false);
270 } 282 }
271 283
272 284
285 bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const {
286 Isolate* owning_isolate = isolate();
287 if (owning_isolate == NULL) {
288 return false;
289 }
290 // If we are restarting or shutting down, we do not want to honor
291 // should_pause_on_start or should_pause_on_exit.
292 return (status != MessageHandler::kRestart &&
293 status != MessageHandler::kShutdown) &&
294 should_pause_on_start() && owning_isolate->is_runnable();
295 }
296
297
298 bool MessageHandler::ShouldPauseOnExit(MessageStatus status) const {
299 Isolate* owning_isolate = isolate();
300 if (owning_isolate == NULL) {
301 return false;
302 }
303 return (status != MessageHandler::kRestart &&
304 status != MessageHandler::kShutdown) &&
305 should_pause_on_exit() && owning_isolate->is_runnable();
306 }
307
308
273 bool MessageHandler::HasOOBMessages() { 309 bool MessageHandler::HasOOBMessages() {
274 MonitorLocker ml(&monitor_); 310 MonitorLocker ml(&monitor_);
275 return !oob_queue_->IsEmpty(); 311 return !oob_queue_->IsEmpty();
276 } 312 }
277 313
278 314
279 static bool ShouldPause(MessageHandler::MessageStatus status) {
280 // If we are restarting or shutting down, we do not want to honor
281 // pause_on_start or pause_on_exit.
282 return (status != MessageHandler::kRestart &&
283 status != MessageHandler::kShutdown);
284 }
285
286
287 void MessageHandler::TaskCallback() { 315 void MessageHandler::TaskCallback() {
288 ASSERT(Isolate::Current() == NULL); 316 ASSERT(Isolate::Current() == NULL);
289 MessageStatus status = kOK; 317 MessageStatus status = kOK;
290 bool run_end_callback = false; 318 bool run_end_callback = false;
291 { 319 {
292 // We will occasionally release and reacquire this monitor in this 320 // We will occasionally release and reacquire this monitor in this
293 // function. Whenever we reacquire the monitor we *must* process 321 // function. Whenever we reacquire the monitor we *must* process
294 // all pending OOB messages, or we may miss a request for vm 322 // all pending OOB messages, or we may miss a request for vm
295 // shutdown. 323 // shutdown.
296 MonitorLocker ml(&monitor_); 324 MonitorLocker ml(&monitor_);
297 if (pause_on_start()) { 325 if (ShouldPauseOnStart(kOK)) {
298 if (!paused_on_start_) { 326 if (!is_paused_on_start()) {
299 // Temporarily release the monitor when calling out to 327 PausedOnStartLocked(true);
300 // NotifyPauseOnStart. This avoids a dead lock that can occur
301 // when this message handler tries to post a message while a
302 // message is being posted to it.
303 paused_on_start_ = true;
304 paused_timestamp_ = OS::GetCurrentTimeMillis();
305 monitor_.Exit();
306 NotifyPauseOnStart();
307 monitor_.Enter();
308 } 328 }
309 // More messages may have come in before we (re)acquired the monitor. 329 // More messages may have come in before we (re)acquired the monitor.
310 status = HandleMessages(false, false); 330 status = HandleMessages(false, false);
311 if (ShouldPause(status) && pause_on_start()) { 331 if (ShouldPauseOnStart(status)) {
312 // Still paused. 332 // Still paused.
313 ASSERT(oob_queue_->IsEmpty()); 333 ASSERT(oob_queue_->IsEmpty());
314 task_ = NULL; // No task in queue. 334 task_ = NULL; // No task in queue.
315 return; 335 return;
316 } else { 336 } else {
317 paused_on_start_ = false; 337 PausedOnStartLocked(false);
318 paused_timestamp_ = -1;
319 } 338 }
320 } 339 }
321 340
322 if (status == kOK) { 341 if (status == kOK) {
323 if (start_callback_) { 342 if (start_callback_) {
324 // Initialize the message handler by running its start function, 343 // Initialize the message handler by running its start function,
325 // if we have one. For an isolate, this will run the isolate's 344 // if we have one. For an isolate, this will run the isolate's
326 // main() function. 345 // main() function.
327 // 346 //
328 // Release the monitor_ temporarily while we call the start callback. 347 // Release the monitor_ temporarily while we call the start callback.
329 monitor_.Exit(); 348 monitor_.Exit();
330 status = start_callback_(callback_data_); 349 status = start_callback_(callback_data_);
331 ASSERT(Isolate::Current() == NULL); 350 ASSERT(Isolate::Current() == NULL);
332 start_callback_ = NULL; 351 start_callback_ = NULL;
333 monitor_.Enter(); 352 monitor_.Enter();
334 } 353 }
335 354
336 // Handle any pending messages for this message handler. 355 // Handle any pending messages for this message handler.
337 if (status != kShutdown) { 356 if (status != kShutdown) {
338 status = HandleMessages((status == kOK), true); 357 status = HandleMessages((status == kOK), true);
339 } 358 }
340 } 359 }
341 360
342 // The isolate exits when it encounters an error or when it no 361 // The isolate exits when it encounters an error or when it no
343 // longer has live ports. 362 // longer has live ports.
344 if (status != kOK || !HasLivePorts()) { 363 if (status != kOK || !HasLivePorts()) {
345 if (ShouldPause(status) && pause_on_exit()) { 364 if (ShouldPauseOnExit(status)) {
346 if (!paused_on_exit_) { 365 if (!is_paused_on_exit()) {
347 if (FLAG_trace_service_pause_events) { 366 if (FLAG_trace_service_pause_events) {
348 OS::PrintErr("Isolate %s paused before exiting. " 367 OS::PrintErr("Isolate %s paused before exiting. "
349 "Use the Observatory to release it.\n", name()); 368 "Use the Observatory to release it.\n", name());
350 } 369 }
351 // Temporarily release the monitor when calling out to 370 PausedOnExitLocked(true);
352 // NotifyPauseOnExit. This avoids a dead lock that can
353 // occur when this message handler tries to post a message
354 // while a message is being posted to it.
355 paused_on_exit_ = true;
356 paused_timestamp_ = OS::GetCurrentTimeMillis();
357 monitor_.Exit();
358 NotifyPauseOnExit();
359 monitor_.Enter();
360
361 // More messages may have come in while we released the monitor. 371 // More messages may have come in while we released the monitor.
362 HandleMessages(false, false); 372 status = HandleMessages(false, false);
363 } 373 }
364 if (ShouldPause(status) && pause_on_exit()) { 374 if (ShouldPauseOnExit(status)) {
365 // Still paused. 375 // Still paused.
366 ASSERT(oob_queue_->IsEmpty()); 376 ASSERT(oob_queue_->IsEmpty());
367 task_ = NULL; // No task in queue. 377 task_ = NULL; // No task in queue.
368 return; 378 return;
369 } else { 379 } else {
370 paused_on_exit_ = false; 380 PausedOnExitLocked(false);
371 paused_timestamp_ = -1;
372 } 381 }
373 } 382 }
374 if (FLAG_trace_isolates) { 383 if (FLAG_trace_isolates) {
375 if (status != kOK && isolate() != NULL) { 384 if (status != kOK && isolate() != NULL) {
376 const Error& error = 385 const Error& error =
377 Error::Handle(isolate()->object_store()->sticky_error()); 386 Error::Handle(isolate()->object_store()->sticky_error());
378 OS::Print("[-] Stopping message handler (%s):\n" 387 OS::Print("[-] Stopping message handler (%s):\n"
379 "\thandler: %s\n" 388 "\thandler: %s\n"
380 "\terror: %s\n", 389 "\terror: %s\n",
381 MessageStatusString(status), name(), error.ToCString()); 390 MessageStatusString(status), name(), error.ToCString());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 445
437 void MessageHandler::decrement_live_ports() { 446 void MessageHandler::decrement_live_ports() {
438 MonitorLocker ml(&monitor_); 447 MonitorLocker ml(&monitor_);
439 #if defined(DEBUG) 448 #if defined(DEBUG)
440 CheckAccess(); 449 CheckAccess();
441 #endif 450 #endif
442 live_ports_--; 451 live_ports_--;
443 } 452 }
444 453
445 454
455 void MessageHandler::PausedOnStart(bool paused) {
456 MonitorLocker ml(&monitor_);
457 PausedOnStartLocked(paused);
458 }
459
460
461 void MessageHandler::PausedOnStartLocked(bool paused) {
462 if (paused) {
463 ASSERT(!is_paused_on_start_);
464 is_paused_on_start_ = true;
465 paused_timestamp_ = OS::GetCurrentTimeMillis();
466 } else {
467 ASSERT(is_paused_on_start_);
468 is_paused_on_start_ = false;
469 paused_timestamp_ = -1;
470 }
471 if (is_paused_on_start_) {
472 // Temporarily release the monitor when calling out to
473 // NotifyPauseOnStart. This avoids a dead lock that can occur
474 // when this message handler tries to post a message while a
475 // message is being posted to it.
476 monitor_.Exit();
477 NotifyPauseOnStart();
478 monitor_.Enter();
479 } else {
480 // Resumed. Clear the resume request of the owning isolate.
481 Isolate* owning_isolate = isolate();
482 if (owning_isolate != NULL) {
483 owning_isolate->GetAndClearResumeRequest();
484 }
485 }
486 }
487
488
489 void MessageHandler::PausedOnExit(bool paused) {
490 MonitorLocker ml(&monitor_);
491 PausedOnExitLocked(paused);
492 }
493
494
495 void MessageHandler::PausedOnExitLocked(bool paused) {
496 if (paused) {
497 ASSERT(!is_paused_on_exit_);
498 is_paused_on_exit_ = true;
499 paused_timestamp_ = OS::GetCurrentTimeMillis();
500 } else {
501 ASSERT(is_paused_on_exit_);
502 is_paused_on_exit_ = false;
503 paused_timestamp_ = -1;
504 }
505 if (is_paused_on_exit_) {
506 // Temporarily release the monitor when calling out to
507 // NotifyPauseOnExit. This avoids a dead lock that can
508 // occur when this message handler tries to post a message
509 // while a message is being posted to it.
510 monitor_.Exit();
511 NotifyPauseOnExit();
512 monitor_.Enter();
513 } else {
514 // Resumed. Clear the resume request of the owning isolate.
515 Isolate* owning_isolate = isolate();
516 if (owning_isolate != NULL) {
517 owning_isolate->GetAndClearResumeRequest();
518 }
519 }
520 }
521
522
446 MessageHandler::AcquiredQueues::AcquiredQueues() 523 MessageHandler::AcquiredQueues::AcquiredQueues()
447 : handler_(NULL) { 524 : handler_(NULL) {
448 } 525 }
449 526
450 527
451 MessageHandler::AcquiredQueues::~AcquiredQueues() { 528 MessageHandler::AcquiredQueues::~AcquiredQueues() {
452 Reset(NULL); 529 Reset(NULL);
453 } 530 }
454 531
455 532
(...skipping 15 matching lines...) Expand all
471 548
472 549
473 void MessageHandler::AcquireQueues(AcquiredQueues* acquired_queues) { 550 void MessageHandler::AcquireQueues(AcquiredQueues* acquired_queues) {
474 ASSERT(acquired_queues != NULL); 551 ASSERT(acquired_queues != NULL);
475 // No double dipping. 552 // No double dipping.
476 ASSERT(acquired_queues->handler_ == NULL); 553 ASSERT(acquired_queues->handler_ == NULL);
477 acquired_queues->Reset(this); 554 acquired_queues->Reset(this);
478 } 555 }
479 556
480 } // namespace dart 557 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/message_handler.h ('k') | runtime/vm/service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698