Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2011 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 #ifndef WEBRTC_BASE_REFCOUNT_H_
     12 #define WEBRTC_BASE_REFCOUNT_H_
     13 
     14 #include <string.h>
     15 
     16 #include "webrtc/base/atomicops.h"
     17 
     18 namespace rtc {
     19 
     20 // Reference count interface.
     21 class RefCountInterface {
     22  public:
     23   virtual int AddRef() const = 0;
     24   virtual int Release() const = 0;
     25  protected:
     26   virtual ~RefCountInterface() {}
     27 };
     28 
     29 template <class T>
     30 class RefCountedObject : public T {
     31  public:
     32   RefCountedObject() : ref_count_(0) {
     33   }
     34 
     35   template<typename P>
     36   explicit RefCountedObject(P p) : T(p), ref_count_(0) {
     37   }
     38 
     39   template<typename P1, typename P2>
     40   RefCountedObject(P1 p1, P2 p2) : T(p1, p2), ref_count_(0) {
     41   }
     42 
     43   template<typename P1, typename P2, typename P3>
     44   RefCountedObject(P1 p1, P2 p2, P3 p3) : T(p1, p2, p3), ref_count_(0) {
     45   }
     46 
     47   template<typename P1, typename P2, typename P3, typename P4>
     48   RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4)
     49       : T(p1, p2, p3, p4), ref_count_(0) {
     50   }
     51 
     52   template<typename P1, typename P2, typename P3, typename P4, typename P5>
     53   RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
     54       : T(p1, p2, p3, p4, p5), ref_count_(0) {
     55   }
     56 
     57   template<typename P1, typename P2, typename P3, typename P4, typename P5,
     58            typename P6>
     59   RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
     60       : T(p1, p2, p3, p4, p5, p6), ref_count_(0) {
     61   }
     62 
     63   template<typename P1, typename P2, typename P3, typename P4, typename P5,
     64            typename P6, typename P7>
     65   RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
     66       : T(p1, p2, p3, p4, p5, p6, p7), ref_count_(0) {
     67   }
     68 
     69   template<typename P1, typename P2, typename P3, typename P4, typename P5,
     70            typename P6, typename P7, typename P8>
     71   RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
     72       : T(p1, p2, p3, p4, p5, p6, p7, p8), ref_count_(0) {
     73   }
     74 
     75   template<typename P1, typename P2, typename P3, typename P4, typename P5,
     76            typename P6, typename P7, typename P8, typename P9>
     77   RefCountedObject(
     78       P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9)
     79   : T(p1, p2, p3, p4, p5, p6, p7, p8, p9), ref_count_(0) {
     80   }
     81 
     82   template<typename P1, typename P2, typename P3, typename P4, typename P5,
     83            typename P6, typename P7, typename P8, typename P9, typename P10>
     84   RefCountedObject(
     85       P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10)
     86   : T(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), ref_count_(0) {
     87   }
     88 
     89   template<typename P1, typename P2, typename P3, typename P4, typename P5,
     90            typename P6, typename P7, typename P8, typename P9, typename P10,
     91            typename P11>
     92   RefCountedObject(
     93       P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10,
     94       P11 p11)
     95   : T(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), ref_count_(0) {
     96   }
     97 
     98   virtual int AddRef() const {
     99     return AtomicOps::Increment(&ref_count_);
    100   }
    101 
    102   virtual int Release() const {
    103     int count = AtomicOps::Decrement(&ref_count_);
    104     if (!count) {
    105       delete this;
    106     }
    107     return count;
    108   }
    109 
    110   // Return whether the reference count is one. If the reference count is used
    111   // in the conventional way, a reference count of 1 implies that the current
    112   // thread owns the reference and no other thread shares it. This call
    113   // performs the test for a reference count of one, and performs the memory
    114   // barrier needed for the owning thread to act on the object, knowing that it
    115   // has exclusive access to the object.
    116   virtual bool HasOneRef() const {
    117     return AtomicOps::AcquireLoad(&ref_count_) == 1;
    118   }
    119 
    120  protected:
    121   virtual ~RefCountedObject() {
    122   }
    123 
    124   mutable volatile int ref_count_;
    125 };
    126 
    127 }  // namespace rtc
    128 
    129 #endif  // WEBRTC_BASE_REFCOUNT_H_
    130