1// Copyright (c) 2012 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 LIBRARIES_SDK_UTIL_REF_OBJECT
6#define LIBRARIES_SDK_UTIL_REF_OBJECT
7
8#include <stdlib.h>
9#include "pthread.h"
10
11#include "sdk_util/atomicops.h"
12
13namespace sdk_util {
14
15class ScopedRefBase;
16
17/*
18 * RefObject
19 *
20 * A reference counted object. RefObjects should only be handled by ScopedRef
21 * objects.
22 *
23 * When the object is first created, it has a reference count of zero.  It's
24 * first incremented when it gets assigned to a ScopedRef.  When the last
25 * ScopedRef is reset or destroyed the object will get released.
26 */
27
28class RefObject {
29 public:
30  RefObject() {
31    ref_count_ = 0;
32  }
33
34  /*
35   * RefCount
36   *
37   * RefCount returns an instantaneous snapshot of the RefCount, which may
38   * change immediately after it is fetched.  This is only stable when all
39   * pointers to the object are scoped pointers (ScopedRef), and the value
40   * is one implying the current thread is the only one, with visibility to
41   * the object.
42   */
43  int RefCount() const { return ref_count_; }
44
45 protected:
46  virtual ~RefObject() {}
47
48  // Override to clean up object when last reference is released.
49  virtual void Destroy() {}
50
51  void Acquire() {
52    AtomicAddFetch(&ref_count_, 1);
53  }
54
55  bool Release() {
56    Atomic32 val = AtomicAddFetch(&ref_count_, -1);
57    if (val == 0) {
58      Destroy();
59      delete this;
60      return false;
61    }
62    return true;
63  }
64
65 private:
66  Atomic32 ref_count_;
67
68  friend class ScopedRefBase;
69};
70
71}  // namespace sdk_util
72
73#endif  // LIBRARIES_SDK_UTIL_REF_OBJECT
74
75