~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/third_party/chromium/src/base/memory/ref_counted.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 BASE_MEMORY_REF_COUNTED_H_
6
 
#define BASE_MEMORY_REF_COUNTED_H_
7
 
 
8
 
#include <cassert>
9
 
 
10
 
#include "base/atomic_ref_count.h"
11
 
#include "base/base_export.h"
12
 
#include "base/compiler_specific.h"
13
 
#ifndef NDEBUG
14
 
#include "base/logging.h"
15
 
#endif
16
 
#include "base/threading/thread_collision_warner.h"
17
 
 
18
 
namespace base {
19
 
 
20
 
namespace subtle {
21
 
 
22
 
class BASE_EXPORT RefCountedBase {
23
 
 public:
24
 
  bool HasOneRef() const { return ref_count_ == 1; }
25
 
 
26
 
 protected:
27
 
  RefCountedBase()
28
 
      : ref_count_(0)
29
 
  #ifndef NDEBUG
30
 
      , in_dtor_(false)
31
 
  #endif
32
 
      {
33
 
  }
34
 
 
35
 
  ~RefCountedBase() {
36
 
  #ifndef NDEBUG
37
 
    DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
38
 
  #endif
39
 
  }
40
 
 
41
 
 
42
 
  void AddRef() const {
43
 
    // TODO(maruel): Add back once it doesn't assert 500 times/sec.
44
 
    // Current thread books the critical section "AddRelease"
45
 
    // without release it.
46
 
    // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
47
 
  #ifndef NDEBUG
48
 
    DCHECK(!in_dtor_);
49
 
  #endif
50
 
    ++ref_count_;
51
 
  }
52
 
 
53
 
  // Returns true if the object should self-delete.
54
 
  bool Release() const {
55
 
    // TODO(maruel): Add back once it doesn't assert 500 times/sec.
56
 
    // Current thread books the critical section "AddRelease"
57
 
    // without release it.
58
 
    // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
59
 
  #ifndef NDEBUG
60
 
    DCHECK(!in_dtor_);
61
 
  #endif
62
 
    if (--ref_count_ == 0) {
63
 
  #ifndef NDEBUG
64
 
      in_dtor_ = true;
65
 
  #endif
66
 
      return true;
67
 
    }
68
 
    return false;
69
 
  }
70
 
 
71
 
 private:
72
 
  mutable int ref_count_;
73
 
#ifndef NDEBUG
74
 
  mutable bool in_dtor_;
75
 
#endif
76
 
 
77
 
  DFAKE_MUTEX(add_release_);
78
 
 
79
 
  DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
80
 
};
81
 
 
82
 
class BASE_EXPORT RefCountedThreadSafeBase {
83
 
 public:
84
 
  bool HasOneRef() const;
85
 
 
86
 
 protected:
87
 
  RefCountedThreadSafeBase();
88
 
  ~RefCountedThreadSafeBase();
89
 
 
90
 
  void AddRef() const;
91
 
 
92
 
  // Returns true if the object should self-delete.
93
 
  bool Release() const;
94
 
 
95
 
 private:
96
 
  mutable AtomicRefCount ref_count_;
97
 
#ifndef NDEBUG
98
 
  mutable bool in_dtor_;
99
 
#endif
100
 
 
101
 
  DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
102
 
};
103
 
 
104
 
}  // namespace subtle
105
 
 
106
 
//
107
 
// A base class for reference counted classes.  Otherwise, known as a cheap
108
 
// knock-off of WebKit's RefCounted<T> class.  To use this guy just extend your
109
 
// class from it like so:
110
 
//
111
 
//   class MyFoo : public base::RefCounted<MyFoo> {
112
 
//    ...
113
 
//    private:
114
 
//     friend class base::RefCounted<MyFoo>;
115
 
//     ~MyFoo();
116
 
//   };
117
 
//
118
 
// You should always make your destructor private, to avoid any code deleting
119
 
// the object accidently while there are references to it.
120
 
template <class T>
121
 
class RefCounted : public subtle::RefCountedBase {
122
 
 public:
123
 
  RefCounted() {}
124
 
 
125
 
  void AddRef() const {
126
 
    subtle::RefCountedBase::AddRef();
127
 
  }
128
 
 
129
 
  void Release() const {
130
 
    if (subtle::RefCountedBase::Release()) {
131
 
      delete static_cast<const T*>(this);
132
 
    }
133
 
  }
134
 
 
135
 
 protected:
136
 
  ~RefCounted() {}
137
 
 
138
 
 private:
139
 
  DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
140
 
};
141
 
 
142
 
// Forward declaration.
143
 
template <class T, typename Traits> class RefCountedThreadSafe;
144
 
 
145
 
// Default traits for RefCountedThreadSafe<T>.  Deletes the object when its ref
146
 
// count reaches 0.  Overload to delete it on a different thread etc.
147
 
template<typename T>
148
 
struct DefaultRefCountedThreadSafeTraits {
149
 
  static void Destruct(const T* x) {
150
 
    // Delete through RefCountedThreadSafe to make child classes only need to be
151
 
    // friend with RefCountedThreadSafe instead of this struct, which is an
152
 
    // implementation detail.
153
 
    RefCountedThreadSafe<T,
154
 
                         DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
155
 
  }
156
 
};
157
 
 
158
 
//
159
 
// A thread-safe variant of RefCounted<T>
160
 
//
161
 
//   class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
162
 
//    ...
163
 
//   };
164
 
//
165
 
// If you're using the default trait, then you should add compile time
166
 
// asserts that no one else is deleting your object.  i.e.
167
 
//    private:
168
 
//     friend class base::RefCountedThreadSafe<MyFoo>;
169
 
//     ~MyFoo();
170
 
template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
171
 
class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
172
 
 public:
173
 
  RefCountedThreadSafe() {}
174
 
 
175
 
  void AddRef() const {
176
 
    subtle::RefCountedThreadSafeBase::AddRef();
177
 
  }
178
 
 
179
 
  void Release() const {
180
 
    if (subtle::RefCountedThreadSafeBase::Release()) {
181
 
      Traits::Destruct(static_cast<const T*>(this));
182
 
    }
183
 
  }
184
 
 
185
 
 protected:
186
 
  ~RefCountedThreadSafe() {}
187
 
 
188
 
 private:
189
 
  friend struct DefaultRefCountedThreadSafeTraits<T>;
190
 
  static void DeleteInternal(const T* x) { delete x; }
191
 
 
192
 
  DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
193
 
};
194
 
 
195
 
//
196
 
// A thread-safe wrapper for some piece of data so we can place other
197
 
// things in scoped_refptrs<>.
198
 
//
199
 
template<typename T>
200
 
class RefCountedData
201
 
    : public base::RefCountedThreadSafe< base::RefCountedData<T> > {
202
 
 public:
203
 
  RefCountedData() : data() {}
204
 
  RefCountedData(const T& in_value) : data(in_value) {}
205
 
 
206
 
  T data;
207
 
 
208
 
 private:
209
 
  friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
210
 
  ~RefCountedData() {}
211
 
};
212
 
 
213
 
}  // namespace base
214
 
 
215
 
//
216
 
// A smart pointer class for reference counted objects.  Use this class instead
217
 
// of calling AddRef and Release manually on a reference counted object to
218
 
// avoid common memory leaks caused by forgetting to Release an object
219
 
// reference.  Sample usage:
220
 
//
221
 
//   class MyFoo : public RefCounted<MyFoo> {
222
 
//    ...
223
 
//   };
224
 
//
225
 
//   void some_function() {
226
 
//     scoped_refptr<MyFoo> foo = new MyFoo();
227
 
//     foo->Method(param);
228
 
//     // |foo| is released when this function returns
229
 
//   }
230
 
//
231
 
//   void some_other_function() {
232
 
//     scoped_refptr<MyFoo> foo = new MyFoo();
233
 
//     ...
234
 
//     foo = NULL;  // explicitly releases |foo|
235
 
//     ...
236
 
//     if (foo)
237
 
//       foo->Method(param);
238
 
//   }
239
 
//
240
 
// The above examples show how scoped_refptr<T> acts like a pointer to T.
241
 
// Given two scoped_refptr<T> classes, it is also possible to exchange
242
 
// references between the two objects, like so:
243
 
//
244
 
//   {
245
 
//     scoped_refptr<MyFoo> a = new MyFoo();
246
 
//     scoped_refptr<MyFoo> b;
247
 
//
248
 
//     b.swap(a);
249
 
//     // now, |b| references the MyFoo object, and |a| references NULL.
250
 
//   }
251
 
//
252
 
// To make both |a| and |b| in the above example reference the same MyFoo
253
 
// object, simply use the assignment operator:
254
 
//
255
 
//   {
256
 
//     scoped_refptr<MyFoo> a = new MyFoo();
257
 
//     scoped_refptr<MyFoo> b;
258
 
//
259
 
//     b = a;
260
 
//     // now, |a| and |b| each own a reference to the same MyFoo object.
261
 
//   }
262
 
//
263
 
template <class T>
264
 
class scoped_refptr {
265
 
 public:
266
 
  typedef T element_type;
267
 
 
268
 
  scoped_refptr() : ptr_(NULL) {
269
 
  }
270
 
 
271
 
  scoped_refptr(T* p) : ptr_(p) {
272
 
    if (ptr_)
273
 
      ptr_->AddRef();
274
 
  }
275
 
 
276
 
  scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
277
 
    if (ptr_)
278
 
      ptr_->AddRef();
279
 
  }
280
 
 
281
 
  template <typename U>
282
 
  scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
283
 
    if (ptr_)
284
 
      ptr_->AddRef();
285
 
  }
286
 
 
287
 
  ~scoped_refptr() {
288
 
    if (ptr_)
289
 
      ptr_->Release();
290
 
  }
291
 
 
292
 
  T* get() const { return ptr_; }
293
 
 
294
 
  // Allow scoped_refptr<C> to be used in boolean expression
295
 
  // and comparison operations.
296
 
  operator T*() const { return ptr_; }
297
 
 
298
 
  T* operator->() const {
299
 
    assert(ptr_ != NULL);
300
 
    return ptr_;
301
 
  }
302
 
 
303
 
  scoped_refptr<T>& operator=(T* p) {
304
 
    // AddRef first so that self assignment should work
305
 
    if (p)
306
 
      p->AddRef();
307
 
    T* old_ptr = ptr_;
308
 
    ptr_ = p;
309
 
    if (old_ptr)
310
 
      old_ptr->Release();
311
 
    return *this;
312
 
  }
313
 
 
314
 
  scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
315
 
    return *this = r.ptr_;
316
 
  }
317
 
 
318
 
  template <typename U>
319
 
  scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
320
 
    return *this = r.get();
321
 
  }
322
 
 
323
 
  void swap(T** pp) {
324
 
    T* p = ptr_;
325
 
    ptr_ = *pp;
326
 
    *pp = p;
327
 
  }
328
 
 
329
 
  void swap(scoped_refptr<T>& r) {
330
 
    swap(&r.ptr_);
331
 
  }
332
 
 
333
 
 protected:
334
 
  T* ptr_;
335
 
};
336
 
 
337
 
// Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
338
 
// having to retype all the template arguments
339
 
template <typename T>
340
 
scoped_refptr<T> make_scoped_refptr(T* t) {
341
 
  return scoped_refptr<T>(t);
342
 
}
343
 
 
344
 
#endif  // BASE_MEMORY_REF_COUNTED_H_