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

Unified Diff: base/threading/sequenced_worker_pool.cc

Issue 2581213002: Force HostContentSettingsMap to be destroyed on its owning thread. (Closed)
Patch Set: s/STRH comparison/RunsTasksOnCurrentThread/ Created 4 years 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
« no previous file with comments | « no previous file | chrome/browser/notifications/notification_permission_context_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/threading/sequenced_worker_pool.cc
diff --git a/base/threading/sequenced_worker_pool.cc b/base/threading/sequenced_worker_pool.cc
index 56bbb62dd09f58bb92f05340598a109e715c5aee..af22098effca47dbeb484d95244f1bd1a928819e 100644
--- a/base/threading/sequenced_worker_pool.cc
+++ b/base/threading/sequenced_worker_pool.cc
@@ -383,6 +383,12 @@ class SequencedWorkerPool::Inner {
CLEANUP_DONE,
};
+ // Clears ScheduledTasks in |tasks_to_delete| while ensuring that
+ // |this_worker| has the desired task info context during ~ScheduledTask() to
+ // allow sequence-checking.
+ void DeleteWithoutLock(std::vector<SequencedTask>* tasks_to_delete,
+ Worker* this_worker);
+
// Helper used by PostTask() to complete the work when redirection is on.
// Returns true if the task may run at some point in the future and false if
// it will definitely not run.
@@ -420,7 +426,7 @@ class SequencedWorkerPool::Inner {
// See the implementation for a more detailed description.
GetWorkStatus GetWork(SequencedTask* task,
TimeDelta* wait_time,
- std::vector<Closure>* delete_these_outside_lock);
+ std::vector<SequencedTask>* delete_these_outside_lock);
void HandleCleanup();
@@ -983,7 +989,7 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) {
// See GetWork for what delete_these_outside_lock is doing.
SequencedTask task;
TimeDelta wait_time;
- std::vector<Closure> delete_these_outside_lock;
+ std::vector<SequencedTask> delete_these_outside_lock;
GetWorkStatus status =
GetWork(&task, &wait_time, &delete_these_outside_lock);
if (status == GET_WORK_FOUND) {
@@ -1000,7 +1006,7 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) {
// already get a signal for each new task, but it doesn't
// hurt.)
SignalHasWork();
- delete_these_outside_lock.clear();
+ DeleteWithoutLock(&delete_these_outside_lock, this_worker);
// Complete thread creation outside the lock if necessary.
if (new_thread_id)
@@ -1031,7 +1037,7 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) {
switch (status) {
case GET_WORK_WAIT: {
AutoUnlock unlock(lock_);
- delete_these_outside_lock.clear();
+ DeleteWithoutLock(&delete_these_outside_lock, this_worker);
}
break;
case GET_WORK_NOT_FOUND:
@@ -1053,7 +1059,7 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) {
// help this case.
if (shutdown_called_ && blocking_shutdown_pending_task_count_ == 0) {
AutoUnlock unlock(lock_);
- delete_these_outside_lock.clear();
+ DeleteWithoutLock(&delete_these_outside_lock, this_worker);
break;
}
@@ -1061,7 +1067,7 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) {
// deletion must happen outside of the lock.
if (delete_these_outside_lock.size()) {
AutoUnlock unlock(lock_);
- delete_these_outside_lock.clear();
+ DeleteWithoutLock(&delete_these_outside_lock, this_worker);
// Since the lock has been released, |status| may no longer be
// accurate. It might read GET_WORK_WAIT even if there are tasks
@@ -1084,6 +1090,9 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) {
}
waiting_thread_count_--;
}
+ // |delete_these_outside_lock| should have been cleared via
+ // DeleteWithoutLock() above already.
+ DCHECK(delete_these_outside_lock.empty());
}
} // Release lock_.
@@ -1095,6 +1104,19 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) {
can_shutdown_cv_.Signal();
}
+void SequencedWorkerPool::Inner::DeleteWithoutLock(
+ std::vector<SequencedTask>* tasks_to_delete,
+ Worker* this_worker) {
+ while (!tasks_to_delete->empty()) {
+ const SequencedTask& deleted_task = tasks_to_delete->back();
+ this_worker->set_running_task_info(
+ SequenceToken(deleted_task.sequence_token_id),
+ deleted_task.shutdown_behavior);
+ tasks_to_delete->pop_back();
+ }
+ this_worker->reset_running_task_info();
+}
+
void SequencedWorkerPool::Inner::HandleCleanup() {
DCHECK_EQ(AllPoolsState::USE_WORKER_POOL, g_all_pools_state);
@@ -1162,7 +1184,7 @@ int64_t SequencedWorkerPool::Inner::LockedGetNextSequenceTaskNumber() {
SequencedWorkerPool::Inner::GetWorkStatus SequencedWorkerPool::Inner::GetWork(
SequencedTask* task,
TimeDelta* wait_time,
- std::vector<Closure>* delete_these_outside_lock) {
+ std::vector<SequencedTask>* delete_these_outside_lock) {
DCHECK_EQ(AllPoolsState::USE_WORKER_POOL, g_all_pools_state);
lock_.AssertAcquired();
@@ -1208,18 +1230,17 @@ SequencedWorkerPool::Inner::GetWorkStatus SequencedWorkerPool::Inner::GetWork(
// shutdown. Delete it and get more work.
//
// Note that we do not want to delete unrunnable tasks. Deleting a task
- // can have side effects (like freeing some objects) and deleting a
- // task that's supposed to run after one that's currently running could
- // cause an obscure crash.
+ // can have side effects (like freeing some objects) and deleting a task
+ // that's supposed to run after one that's currently running could cause
+ // an obscure crash.
//
// We really want to delete these tasks outside the lock in case the
- // closures are holding refs to objects that want to post work from
- // their destructorss (which would deadlock). The closures are
- // internally refcounted, so we just need to keep a copy of them alive
- // until the lock is exited. The calling code can just clear() the
- // vector they passed to us once the lock is exited to make this
- // happen.
- delete_these_outside_lock->push_back(i->task);
+ // closures are holding refs to objects that want to post work from their
+ // destructors (which would deadlock). The closures are internally
+ // refcounted, so we just need to keep a copy of them alive until the lock
+ // is exited. The calling code can just clear() the vector they passed to
+ // us once the lock is exited to make this happen.
+ delete_these_outside_lock->push_back(*i);
pending_tasks_.erase(i++);
continue;
}
@@ -1230,7 +1251,7 @@ SequencedWorkerPool::Inner::GetWorkStatus SequencedWorkerPool::Inner::GetWork(
status = GET_WORK_WAIT;
if (cleanup_state_ == CLEANUP_RUNNING) {
// Deferred tasks are deleted when cleaning up, see Inner::ThreadLoop.
- delete_these_outside_lock->push_back(i->task);
+ delete_these_outside_lock->push_back(*i);
pending_tasks_.erase(i);
}
break;
« no previous file with comments | « no previous file | chrome/browser/notifications/notification_permission_context_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698