1/*
2 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <algorithm>
12
13#include "webrtc/base/taskparent.h"
14
15#include "webrtc/base/task.h"
16#include "webrtc/base/taskrunner.h"
17
18namespace rtc {
19
20TaskParent::TaskParent(Task* derived_instance, TaskParent *parent)
21    : parent_(parent) {
22  ASSERT(derived_instance != NULL);
23  ASSERT(parent != NULL);
24  runner_ = parent->GetRunner();
25  parent_->AddChild(derived_instance);
26  Initialize();
27}
28
29TaskParent::TaskParent(TaskRunner *derived_instance)
30    : parent_(NULL),
31      runner_(derived_instance) {
32  ASSERT(derived_instance != NULL);
33  Initialize();
34}
35
36// Does common initialization of member variables
37void TaskParent::Initialize() {
38  children_.reset(new ChildSet());
39  child_error_ = false;
40}
41
42void TaskParent::AddChild(Task *child) {
43  children_->insert(child);
44}
45
46#ifdef _DEBUG
47bool TaskParent::IsChildTask(Task *task) {
48  ASSERT(task != NULL);
49  return task->parent_ == this && children_->find(task) != children_->end();
50}
51#endif
52
53bool TaskParent::AllChildrenDone() {
54  for (ChildSet::iterator it = children_->begin();
55       it != children_->end();
56       ++it) {
57    if (!(*it)->IsDone())
58      return false;
59  }
60  return true;
61}
62
63bool TaskParent::AnyChildError() {
64  return child_error_;
65}
66
67void TaskParent::AbortAllChildren() {
68  if (children_->size() > 0) {
69#ifdef _DEBUG
70    runner_->IncrementAbortCount();
71#endif
72
73    ChildSet copy = *children_;
74    for (ChildSet::iterator it = copy.begin(); it != copy.end(); ++it) {
75      (*it)->Abort(true);  // Note we do not wake
76    }
77
78#ifdef _DEBUG
79    runner_->DecrementAbortCount();
80#endif
81  }
82}
83
84void TaskParent::OnStopped(Task *task) {
85  AbortAllChildren();
86  parent_->OnChildStopped(task);
87}
88
89void TaskParent::OnChildStopped(Task *child) {
90  if (child->HasError())
91    child_error_ = true;
92  children_->erase(child);
93}
94
95} // namespace rtc
96