Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2004--2006, Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include <algorithm>
     29 
     30 #include "talk/base/taskparent.h"
     31 
     32 #include "talk/base/task.h"
     33 #include "talk/base/taskrunner.h"
     34 
     35 namespace talk_base {
     36 
     37 TaskParent::TaskParent(Task* derived_instance, TaskParent *parent)
     38     : parent_(parent) {
     39   ASSERT(derived_instance != NULL);
     40   ASSERT(parent != NULL);
     41   runner_ = parent->GetRunner();
     42   parent_->AddChild(derived_instance);
     43   Initialize();
     44 }
     45 
     46 TaskParent::TaskParent(TaskRunner *derived_instance)
     47     : parent_(NULL),
     48       runner_(derived_instance) {
     49   ASSERT(derived_instance != NULL);
     50   Initialize();
     51 }
     52 
     53 // Does common initialization of member variables
     54 void TaskParent::Initialize() {
     55   children_.reset(new ChildSet());
     56   child_error_ = false;
     57 }
     58 
     59 void TaskParent::AddChild(Task *child) {
     60   children_->insert(child);
     61 }
     62 
     63 #ifdef _DEBUG
     64 bool TaskParent::IsChildTask(Task *task) {
     65   ASSERT(task != NULL);
     66   return task->parent_ == this && children_->find(task) != children_->end();
     67 }
     68 #endif
     69 
     70 bool TaskParent::AllChildrenDone() {
     71   for (ChildSet::iterator it = children_->begin();
     72        it != children_->end();
     73        ++it) {
     74     if (!(*it)->IsDone())
     75       return false;
     76   }
     77   return true;
     78 }
     79 
     80 bool TaskParent::AnyChildError() {
     81   return child_error_;
     82 }
     83 
     84 void TaskParent::AbortAllChildren() {
     85   if (children_->size() > 0) {
     86 #ifdef _DEBUG
     87     runner_->IncrementAbortCount();
     88 #endif
     89 
     90     ChildSet copy = *children_;
     91     for (ChildSet::iterator it = copy.begin(); it != copy.end(); ++it) {
     92       (*it)->Abort(true);  // Note we do not wake
     93     }
     94 
     95 #ifdef _DEBUG
     96     runner_->DecrementAbortCount();
     97 #endif
     98   }
     99 }
    100 
    101 void TaskParent::OnStopped(Task *task) {
    102   AbortAllChildren();
    103   parent_->OnChildStopped(task);
    104 }
    105 
    106 void TaskParent::OnChildStopped(Task *child) {
    107   if (child->HasError())
    108     child_error_ = true;
    109   children_->erase(child);
    110 }
    111 
    112 } // namespace talk_base
    113