@@ -371,6 +371,7 @@ void CompileQueue::delete_all() {
371371
372372 // Iterate over all tasks in the compile queue
373373 while (current != nullptr ) {
374+ CompileTask* next = current->next ();
374375 if (!current->is_blocking ()) {
375376 // Non-blocking task. No one is waiting for it, delete it now.
376377 delete current;
@@ -379,7 +380,7 @@ void CompileQueue::delete_all() {
379380 // to delete the task. We cannot delete it here, because we do not
380381 // coordinate with waiters. We will notify the waiters later.
381382 }
382- current = current-> next () ;
383+ current = next;
383384 }
384385 _first = nullptr ;
385386 _last = nullptr ;
@@ -504,6 +505,8 @@ void CompileQueue::remove(CompileTask* task) {
504505 assert (task == _last, " Sanity" );
505506 _last = task->prev ();
506507 }
508+ task->set_next (nullptr );
509+ task->set_prev (nullptr );
507510 --_size;
508511 ++_total_removed;
509512}
@@ -1728,17 +1731,22 @@ void CompileBroker::wait_for_completion(CompileTask* task) {
17281731
17291732 // It is harmless to check this status without the lock, because
17301733 // completion is a stable property.
1731- if (!task->is_complete () && is_compilation_disabled_forever ()) {
1732- // Task is not complete, and we are exiting for compilation shutdown.
1733- // The task can still be executed by some compiler thread, therefore
1734- // we cannot delete it. This will leave task allocated, which leaks it.
1735- // At this (degraded) point, it is less risky to abandon the task,
1736- // rather than attempting a more complicated deletion protocol.
1734+ if (!task->is_complete ()) {
1735+ // Task is not complete, likely because we are exiting for compilation
1736+ // shutdown. The task can still be reached through the queue, or executed
1737+ // by some compiler thread. There is no coordination with either MCQ lock
1738+ // holders or compilers, therefore we cannot delete the task.
1739+ //
1740+ // This will leave task allocated, which leaks it. At this (degraded) point,
1741+ // it is less risky to abandon the task, rather than attempting a more
1742+ // complicated deletion protocol.
17371743 free_task = false ;
17381744 }
17391745
17401746 if (free_task) {
17411747 assert (task->is_complete (), " Compilation should have completed" );
1748+ assert (task->next () == nullptr && task->prev () == nullptr ,
1749+ " Completed task should not be in the queue" );
17421750
17431751 // By convention, the waiter is responsible for deleting a
17441752 // blocking CompileTask. Since there is only one waiter ever
0 commit comments