Index: src/cancelable-task.cc |
diff --git a/src/cancelable-task.cc b/src/cancelable-task.cc |
index d231bb799d56621b56c931c88fb72e8d27c32591..defbb44775a8c1f64b8eedac62ea21b8376eacd1 100644 |
--- a/src/cancelable-task.cc |
+++ b/src/cancelable-task.cc |
@@ -14,7 +14,6 @@ namespace internal { |
Cancelable::Cancelable(CancelableTaskManager* parent) |
: parent_(parent), status_(kWaiting), id_(0), cancel_counter_(0) { |
id_ = parent->Register(this); |
- CHECK(id_ != 0); |
} |
@@ -27,49 +26,35 @@ Cancelable::~Cancelable() { |
} |
} |
- |
-static bool ComparePointers(void* ptr1, void* ptr2) { return ptr1 == ptr2; } |
- |
- |
-CancelableTaskManager::CancelableTaskManager() |
- : task_id_counter_(0), cancelable_tasks_(ComparePointers) {} |
- |
+CancelableTaskManager::CancelableTaskManager() : task_id_counter_(0) {} |
uint32_t CancelableTaskManager::Register(Cancelable* task) { |
base::LockGuard<base::Mutex> guard(&mutex_); |
uint32_t id = ++task_id_counter_; |
// The loop below is just used when task_id_counter_ overflows. |
- while ((id == 0) || (cancelable_tasks_.Lookup(reinterpret_cast<void*>(id), |
- id) != nullptr)) { |
- ++id; |
- } |
- HashMap::Entry* entry = |
- cancelable_tasks_.LookupOrInsert(reinterpret_cast<void*>(id), id); |
- entry->value = task; |
+ while (cancelable_tasks_.count(id) > 0) ++id; |
+ cancelable_tasks_[id] = task; |
return id; |
} |
void CancelableTaskManager::RemoveFinishedTask(uint32_t id) { |
base::LockGuard<base::Mutex> guard(&mutex_); |
- void* removed = cancelable_tasks_.Remove(reinterpret_cast<void*>(id), id); |
+ size_t removed = cancelable_tasks_.erase(id); |
USE(removed); |
- DCHECK(removed != nullptr); |
+ DCHECK_NE(0, removed); |
cancelable_tasks_barrier_.NotifyOne(); |
} |
bool CancelableTaskManager::TryAbort(uint32_t id) { |
base::LockGuard<base::Mutex> guard(&mutex_); |
- HashMap::Entry* entry = |
- cancelable_tasks_.Lookup(reinterpret_cast<void*>(id), id); |
- if (entry != nullptr) { |
- Cancelable* value = reinterpret_cast<Cancelable*>(entry->value); |
+ auto entry = cancelable_tasks_.find(id); |
+ if (entry != cancelable_tasks_.end()) { |
+ Cancelable* value = entry->second; |
if (value->Cancel()) { |
// Cannot call RemoveFinishedTask here because of recursive locking. |
- void* removed = cancelable_tasks_.Remove(reinterpret_cast<void*>(id), id); |
- USE(removed); |
- DCHECK(removed != nullptr); |
+ cancelable_tasks_.erase(entry); |
cancelable_tasks_barrier_.NotifyOne(); |
return true; |
} |
@@ -85,27 +70,19 @@ void CancelableTaskManager::CancelAndWait() { |
// started. |
base::LockGuard<base::Mutex> guard(&mutex_); |
- // HashMap does not support removing while iterating, hence keep a set of |
- // entries that are to be removed. |
- std::set<uint32_t> to_remove; |
- |
- // Cancelable tasks could potentially register new tasks, requiring a loop |
- // here. |
- while (cancelable_tasks_.occupancy() > 0) { |
- for (HashMap::Entry* p = cancelable_tasks_.Start(); p != nullptr; |
- p = cancelable_tasks_.Next(p)) { |
- if (reinterpret_cast<Cancelable*>(p->value)->Cancel()) { |
- to_remove.insert(reinterpret_cast<Cancelable*>(p->value)->id()); |
+ // Cancelable tasks could be running or could potentially register new |
+ // tasks, requiring a loop here. |
+ while (!cancelable_tasks_.empty()) { |
+ for (auto it = cancelable_tasks_.begin(); it != cancelable_tasks_.end();) { |
+ auto current = it; |
+ // We need to get to the next element before erasing the current. |
+ ++it; |
+ if (current->second->Cancel()) { |
+ cancelable_tasks_.erase(current); |
} |
} |
- // Remove tasks that were successfully canceled. |
- for (auto id : to_remove) { |
- cancelable_tasks_.Remove(reinterpret_cast<void*>(id), id); |
- } |
- to_remove.clear(); |
- |
- // Finally, wait for already running background tasks. |
- if (cancelable_tasks_.occupancy() > 0) { |
+ // Wait for already running background tasks. |
+ if (!cancelable_tasks_.empty()) { |
cancelable_tasks_barrier_.Wait(&mutex_); |
} |
} |