@@ -238,7 +238,6 @@ void MessageHandler::TaskCallback() {
238
238
ASSERT (Isolate::Current () == NULL );
239
239
bool ok = true ;
240
240
bool run_end_callback = false ;
241
- bool notify_paused_on_exit = false ;
242
241
{
243
242
MonitorLocker ml (&monitor_);
244
243
// Initialize the message handler by running its start function,
@@ -255,9 +254,11 @@ void MessageHandler::TaskCallback() {
255
254
NotifyPauseOnStart ();
256
255
monitor_.Enter ();
257
256
}
257
+ // More messages may have come in while we released monitor_.
258
258
HandleMessages (false , false );
259
259
if (pause_on_start ()) {
260
260
// Still paused.
261
+ ASSERT (oob_queue_->IsEmpty ());
261
262
task_ = NULL ; // No task in queue.
262
263
return ;
263
264
} else {
@@ -280,36 +281,50 @@ void MessageHandler::TaskCallback() {
280
281
if (ok) {
281
282
ok = HandleMessages (true , true );
282
283
}
283
- task_ = NULL ; // No task in queue.
284
284
285
285
if (!ok || !HasLivePorts ()) {
286
286
if (pause_on_exit ()) {
287
287
if (!paused_on_exit_) {
288
288
if (FLAG_trace_service_pause_events) {
289
289
OS::PrintErr (" Isolate %s paused before exiting. "
290
- " Use the Observatory to release it.\n " , name ());
290
+ " Use the Observatory to release it.\n " , name ());
291
291
}
292
- notify_paused_on_exit = true ;
292
+ // Temporarily drop the lock when calling out to NotifyPauseOnExit.
293
+ // This avoids a dead lock that can occur when this message handler
294
+ // tries to post a message while a message is being posted to it.
293
295
paused_on_exit_ = true ;
294
296
paused_timestamp_ = OS::GetCurrentTimeMillis ();
297
+ monitor_.Exit ();
298
+ NotifyPauseOnExit ();
299
+ monitor_.Enter ();
295
300
}
296
- } else {
297
- if (FLAG_trace_isolates) {
301
+ // More messages may have come in while we released monitor_.
302
+ HandleMessages (false , false );
303
+ if (pause_on_exit ()) {
304
+ // Still paused.
305
+ ASSERT (oob_queue_->IsEmpty ());
306
+ task_ = NULL ; // No task in queue.
307
+ return ;
308
+ } else {
309
+ paused_on_exit_ = false ;
310
+ paused_timestamp_ = -1 ;
311
+ }
312
+ }
313
+ if (FLAG_trace_isolates) {
298
314
OS::Print (" [-] Stopping message handler (%s):\n "
299
315
" \t handler: %s\n " ,
300
316
(ok ? " no live ports" : " error" ),
301
317
name ());
302
- }
303
- pool_ = NULL ;
304
- run_end_callback = true ;
305
- paused_on_exit_ = false ;
306
- paused_timestamp_ = -1 ;
307
318
}
319
+ pool_ = NULL ;
320
+ run_end_callback = true ;
308
321
}
309
- }
310
- // At this point we no longer hold the message handler lock.
311
- if (notify_paused_on_exit) {
312
- NotifyPauseOnExit ();
322
+
323
+ // Clear the task_ last. We don't want any other tasks to start up
324
+ // until we are done with all messages and pause notifications.
325
+ ASSERT (oob_queue_->IsEmpty ());
326
+ ASSERT (!ok || queue_->IsEmpty ());
327
+ task_ = NULL ;
313
328
}
314
329
if (run_end_callback && end_callback_ != NULL ) {
315
330
end_callback_ (callback_data_);
0 commit comments