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#ifndef CC_BASE_REF_COUNTED_MANAGED_H_
6#define CC_BASE_REF_COUNTED_MANAGED_H_
7
8#include "base/logging.h"
9#include "base/memory/ref_counted.h"
10#include "cc/base/cc_export.h"
11
12namespace cc {
13
14template <typename T> class RefCountedManaged;
15
16template <typename T>
17class CC_EXPORT RefCountedManager {
18 protected:
19  RefCountedManager() : live_object_count_(0) {}
20  ~RefCountedManager() {
21    CHECK_EQ(0, live_object_count_);
22  }
23
24  virtual void Release(T* object) = 0;
25
26 private:
27  friend class RefCountedManaged<T>;
28  int live_object_count_;
29};
30
31template <typename T>
32class CC_EXPORT RefCountedManaged : public base::subtle::RefCountedBase {
33 public:
34  explicit RefCountedManaged(RefCountedManager<T>* manager)
35      : manager_(manager) {
36    manager_->live_object_count_++;
37  }
38
39  void AddRef() const {
40    base::subtle::RefCountedBase::AddRef();
41  }
42
43  void Release() {
44    if (base::subtle::RefCountedBase::Release()) {
45      DCHECK_GT(manager_->live_object_count_, 0);
46      manager_->live_object_count_--;
47
48      // This must be the last statement in case manager deletes
49      // the object immediately.
50      manager_->Release(static_cast<T*>(this));
51    }
52  }
53
54 protected:
55  ~RefCountedManaged() {}
56
57 private:
58  RefCountedManager<T>* manager_;
59
60  DISALLOW_COPY_AND_ASSIGN(RefCountedManaged<T>);
61};
62
63}  // namespace cc
64
65#endif  // CC_BASE_REF_COUNTED_MANAGED_H_
66