Index: webrtc/base/taskrunner.cc |
diff --git a/webrtc/base/taskrunner.cc b/webrtc/base/taskrunner.cc |
deleted file mode 100644 |
index 79e48ecddfa8bcb387f3e6b6caf64a2d13af2122..0000000000000000000000000000000000000000 |
--- a/webrtc/base/taskrunner.cc |
+++ /dev/null |
@@ -1,217 +0,0 @@ |
-/* |
- * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
- * |
- * Use of this source code is governed by a BSD-style license |
- * that can be found in the LICENSE file in the root of the source |
- * tree. An additional intellectual property rights grant can be found |
- * in the file PATENTS. All contributing project authors may |
- * be found in the AUTHORS file in the root of the source tree. |
- */ |
- |
-#include <algorithm> |
- |
-#include "webrtc/base/taskrunner.h" |
- |
-#include "webrtc/base/checks.h" |
-#include "webrtc/base/task.h" |
-#include "webrtc/base/logging.h" |
- |
-namespace rtc { |
- |
-TaskRunner::TaskRunner() |
- : TaskParent(this) {} |
- |
-TaskRunner::~TaskRunner() { |
- // this kills and deletes children silently! |
- AbortAllChildren(); |
- InternalRunTasks(true); |
-} |
- |
-void TaskRunner::StartTask(Task * task) { |
- tasks_.push_back(task); |
- |
- // the task we just started could be about to timeout -- |
- // make sure our "next timeout task" is correct |
- UpdateTaskTimeout(task, 0); |
- |
- WakeTasks(); |
-} |
- |
-void TaskRunner::RunTasks() { |
- InternalRunTasks(false); |
-} |
- |
-void TaskRunner::InternalRunTasks(bool in_destructor) { |
- // This shouldn't run while an abort is happening. |
- // If that occurs, then tasks may be deleted in this method, |
- // but pointers to them will still be in the |
- // "ChildSet copy" in TaskParent::AbortAllChildren. |
- // Subsequent use of those task may cause data corruption or crashes. |
-#if RTC_DCHECK_IS_ON |
- RTC_DCHECK(!abort_count_); |
-#endif |
- // Running continues until all tasks are Blocked (ok for a small # of tasks) |
- if (tasks_running_) { |
- return; // don't reenter |
- } |
- |
- tasks_running_ = true; |
- |
- int64_t previous_timeout_time = next_task_timeout(); |
- |
- int did_run = true; |
- while (did_run) { |
- did_run = false; |
- // use indexing instead of iterators because tasks_ may grow |
- for (size_t i = 0; i < tasks_.size(); ++i) { |
- while (!tasks_[i]->Blocked()) { |
- tasks_[i]->Step(); |
- did_run = true; |
- } |
- } |
- } |
- // Tasks are deleted when running has paused |
- bool need_timeout_recalc = false; |
- for (size_t i = 0; i < tasks_.size(); ++i) { |
- if (tasks_[i]->IsDone()) { |
- Task* task = tasks_[i]; |
- if (next_timeout_task_ && |
- task->unique_id() == next_timeout_task_->unique_id()) { |
- next_timeout_task_ = NULL; |
- need_timeout_recalc = true; |
- } |
- |
-#if RTC_DCHECK_IS_ON |
- deleting_task_ = task; |
-#endif |
- delete task; |
-#if RTC_DCHECK_IS_ON |
- deleting_task_ = NULL; |
-#endif |
- tasks_[i] = NULL; |
- } |
- } |
- // Finally, remove nulls |
- std::vector<Task *>::iterator it; |
- it = std::remove(tasks_.begin(), |
- tasks_.end(), |
- reinterpret_cast<Task *>(NULL)); |
- |
- tasks_.erase(it, tasks_.end()); |
- |
- if (need_timeout_recalc) |
- RecalcNextTimeout(NULL); |
- |
- // Make sure that adjustments are done to account |
- // for any timeout changes (but don't call this |
- // while being destroyed since it calls a pure virtual function). |
- if (!in_destructor) |
- CheckForTimeoutChange(previous_timeout_time); |
- |
- tasks_running_ = false; |
-} |
- |
-void TaskRunner::PollTasks() { |
- // see if our "next potentially timed-out task" has indeed timed out. |
- // If it has, wake it up, then queue up the next task in line |
- // Repeat while we have new timed-out tasks. |
- // TODO: We need to guard against WakeTasks not updating |
- // next_timeout_task_. Maybe also add documentation in the header file once |
- // we understand this code better. |
- Task* old_timeout_task = NULL; |
- while (next_timeout_task_ && |
- old_timeout_task != next_timeout_task_ && |
- next_timeout_task_->TimedOut()) { |
- old_timeout_task = next_timeout_task_; |
- next_timeout_task_->Wake(); |
- WakeTasks(); |
- } |
-} |
- |
-int64_t TaskRunner::next_task_timeout() const { |
- if (next_timeout_task_) { |
- return next_timeout_task_->timeout_time(); |
- } |
- return 0; |
-} |
- |
-// this function gets called frequently -- when each task changes |
-// state to something other than DONE, ERROR or BLOCKED, it calls |
-// ResetTimeout(), which will call this function to make sure that |
-// the next timeout-able task hasn't changed. The logic in this function |
-// prevents RecalcNextTimeout() from getting called in most cases, |
-// effectively making the task scheduler O-1 instead of O-N |
- |
-void TaskRunner::UpdateTaskTimeout(Task* task, |
- int64_t previous_task_timeout_time) { |
- RTC_DCHECK(task != NULL); |
- int64_t previous_timeout_time = next_task_timeout(); |
- bool task_is_timeout_task = next_timeout_task_ != NULL && |
- task->unique_id() == next_timeout_task_->unique_id(); |
- if (task_is_timeout_task) { |
- previous_timeout_time = previous_task_timeout_time; |
- } |
- |
- // if the relevant task has a timeout, then |
- // check to see if it's closer than the current |
- // "about to timeout" task |
- if (task->timeout_time()) { |
- if (next_timeout_task_ == NULL || |
- (task->timeout_time() <= next_timeout_task_->timeout_time())) { |
- next_timeout_task_ = task; |
- } |
- } else if (task_is_timeout_task) { |
- // otherwise, if the task doesn't have a timeout, |
- // and it used to be our "about to timeout" task, |
- // walk through all the tasks looking for the real |
- // "about to timeout" task |
- RecalcNextTimeout(task); |
- } |
- |
- // Note when task_running_, then the running routine |
- // (TaskRunner::InternalRunTasks) is responsible for calling |
- // CheckForTimeoutChange. |
- if (!tasks_running_) { |
- CheckForTimeoutChange(previous_timeout_time); |
- } |
-} |
- |
-void TaskRunner::RecalcNextTimeout(Task *exclude_task) { |
- // walk through all the tasks looking for the one |
- // which satisfies the following: |
- // it's not finished already |
- // we're not excluding it |
- // it has the closest timeout time |
- |
- int64_t next_timeout_time = 0; |
- next_timeout_task_ = NULL; |
- |
- for (size_t i = 0; i < tasks_.size(); ++i) { |
- Task *task = tasks_[i]; |
- // if the task isn't complete, and it actually has a timeout time |
- if (!task->IsDone() && (task->timeout_time() > 0)) |
- // if it doesn't match our "exclude" task |
- if (exclude_task == NULL || |
- exclude_task->unique_id() != task->unique_id()) |
- // if its timeout time is sooner than our current timeout time |
- if (next_timeout_time == 0 || |
- task->timeout_time() <= next_timeout_time) { |
- // set this task as our next-to-timeout |
- next_timeout_time = task->timeout_time(); |
- next_timeout_task_ = task; |
- } |
- } |
-} |
- |
-void TaskRunner::CheckForTimeoutChange(int64_t previous_timeout_time) { |
- int64_t next_timeout = next_task_timeout(); |
- bool timeout_change = (previous_timeout_time == 0 && next_timeout != 0) || |
- next_timeout < previous_timeout_time || |
- (previous_timeout_time <= CurrentTime() && |
- previous_timeout_time != next_timeout); |
- if (timeout_change) { |
- OnTimeoutChange(); |
- } |
-} |
- |
-} // namespace rtc |