Home | History | Annotate | Download | only in base
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/barrier_closure.h"
      6 
      7 #include "base/atomic_ref_count.h"
      8 #include "base/bind.h"
      9 
     10 namespace {
     11 
     12 // Maintains state for a BarrierClosure.
     13 class BarrierInfo {
     14  public:
     15   BarrierInfo(int num_callbacks_left, const base::Closure& done_closure);
     16   void Run();
     17 
     18  private:
     19   base::AtomicRefCount num_callbacks_left_;
     20   base::Closure done_closure_;
     21 };
     22 
     23 BarrierInfo::BarrierInfo(int num_callbacks, const base::Closure& done_closure)
     24     : num_callbacks_left_(num_callbacks),
     25       done_closure_(done_closure) {
     26 }
     27 
     28 void BarrierInfo::Run() {
     29   DCHECK(!base::AtomicRefCountIsZero(&num_callbacks_left_));
     30   if (!base::AtomicRefCountDec(&num_callbacks_left_)) {
     31     done_closure_.Run();
     32     done_closure_.Reset();
     33   }
     34 }
     35 
     36 }  // namespace
     37 
     38 namespace base {
     39 
     40 base::Closure BarrierClosure(int num_callbacks_left,
     41                              const base::Closure& done_closure) {
     42   DCHECK(num_callbacks_left >= 0);
     43 
     44   if (num_callbacks_left == 0)
     45     done_closure.Run();
     46 
     47   return base::Bind(&BarrierInfo::Run,
     48                     base::Owned(
     49                         new BarrierInfo(num_callbacks_left, done_closure)));
     50 }
     51 
     52 }  // namespace base
     53