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

Unified Diff: content/child/scheduler/task_queue_manager.cc

Issue 1072473002: Speculative patch: Make it safe to delete the TQM inside a Task (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added some comments Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: content/child/scheduler/task_queue_manager.cc
diff --git a/content/child/scheduler/task_queue_manager.cc b/content/child/scheduler/task_queue_manager.cc
index 386ebd0c955cc642f6ea09c8db56d004d33e9a41..f3bd5b96ebb70a83e3f92c83d742ed6490764857 100644
--- a/content/child/scheduler/task_queue_manager.cc
+++ b/content/child/scheduler/task_queue_manager.cc
@@ -464,6 +464,7 @@ TaskQueueManager::TaskQueueManager(
time_source_(nullptr),
disabled_by_default_tracing_category_(
disabled_by_default_tracing_category),
+ deletion_sentinel_(new DeletionSentinel()),
weak_factory_(this) {
DCHECK(main_task_runner->RunsTasksOnCurrentThread());
TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category,
@@ -596,7 +597,9 @@ void TaskQueueManager::DoWork(bool posted_from_main_thread) {
// Note that this function won't post another call to DoWork if one is
// already pending, so it is safe to call it in a loop.
MaybePostDoWorkOnMainRunner();
- ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task);
+
+ if (ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task))
+ return; // The TaskQueueManager got deleted, we must bail out.
if (!UpdateWorkQueues(&previous_task))
return;
@@ -616,11 +619,12 @@ void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) {
task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task);
}
-void TaskQueueManager::ProcessTaskFromWorkQueue(
+bool TaskQueueManager::ProcessTaskFromWorkQueue(
size_t queue_index,
bool has_previous_task,
base::PendingTask* previous_task) {
DCHECK(main_thread_checker_.CalledOnValidThread());
+ scoped_refptr<DeletionSentinel> protect(deletion_sentinel_);
internal::TaskQueue* queue = Queue(queue_index);
base::PendingTask pending_task = queue->TakeTaskFromWorkQueue();
if (!pending_task.nestable && main_task_runner_->IsNested()) {
@@ -640,9 +644,16 @@ void TaskQueueManager::ProcessTaskFromWorkQueue(
}
task_annotator_.RunTask("TaskQueueManager::PostTask",
"TaskQueueManager::RunTask", pending_task);
+
+ // Detect if the TaskQueueManager just got deleted. If this happens we must
+ // not access any member variables after this point.
+ if (protect->HasOneRef())
+ return true;
+
pending_task.task.Reset();
*previous_task = pending_task;
}
+ return false;
}
bool TaskQueueManager::RunsTasksOnCurrentThread() const {
« no previous file with comments | « content/child/scheduler/task_queue_manager.h ('k') | content/child/scheduler/task_queue_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698