MongoDB  2.7.0
intrusive_counter.h
1 
29 #pragma once
30 
31 #include <boost/intrusive_ptr.hpp>
32 #include <boost/noncopyable.hpp>
33 #include "mongo/platform/atomic_word.h"
34 #include "mongo/base/string_data.h"
35 
36 namespace mongo {
37 
38 /*
39  IntrusiveCounter is a sharable implementation of a reference counter that
40  objects can use to be compatible with boost::intrusive_ptr<>.
41 
42  Some objects that use IntrusiveCounter are immutable, and only have
43  const methods. This may require their pointers to be declared as
44  intrusive_ptr<const ClassName> . In order to be able to share pointers to
45  these immutables, the methods associated with IntrusiveCounter are declared
46  as const, and the counter itself is marked as mutable.
47 
48  IntrusiveCounter itself is abstract, allowing for multiple implementations.
49  For example, IntrusiveCounterUnsigned uses ordinary unsigned integers for
50  the reference count, and is good for situations where thread safety is not
51  required. For others, other implementations using atomic integers should
52  be used. For static objects, the implementations of addRef() and release()
53  can be overridden to do nothing.
54  */
56  boost::noncopyable {
57  public:
58  virtual ~IntrusiveCounter() {};
59 
60  // these are here for the boost intrusive_ptr<> class
61  friend inline void intrusive_ptr_add_ref(const IntrusiveCounter *pIC) {
62  pIC->addRef(); };
63  friend inline void intrusive_ptr_release(const IntrusiveCounter *pIC) {
64  pIC->release(); };
65 
66  virtual void addRef() const = 0;
67  virtual void release() const = 0;
68  };
69 
71  public IntrusiveCounter {
72  public:
73  // virtuals from IntrusiveCounter
74  virtual void addRef() const;
75  virtual void release() const;
76 
78 
79  private:
80  mutable unsigned counter;
81  };
82 
84  class RefCountable : boost::noncopyable {
85  public:
87  bool isShared() const {
88  // TODO: switch to unfenced read method after SERVER-6973
89  return reinterpret_cast<unsigned&>(_count) > 1;
90  }
91 
92  friend void intrusive_ptr_add_ref(const RefCountable* ptr) {
93  ptr->_count.addAndFetch(1);
94  };
95 
96  friend void intrusive_ptr_release(const RefCountable* ptr) {
97  if (ptr->_count.subtractAndFetch(1) == 0) {
98  delete ptr; // uses subclass destructor and operator delete
99  }
100  };
101 
102  protected:
103  RefCountable() {}
104  virtual ~RefCountable() {}
105 
106  private:
107  mutable AtomicUInt32 _count; // default initialized to 0
108  };
109 
111  class RCString : public RefCountable {
112  public:
113  const char* c_str() const { return reinterpret_cast<const char*>(this) + sizeof(RCString); }
114  int size() const { return _size; }
115  StringData stringData() const { return StringData(c_str(), _size); }
116 
117  static intrusive_ptr<const RCString> create(StringData s);
118 
119 // MSVC: C4291: 'declaration' : no matching operator delete found; memory will not be freed if
120 // initialization throws an exception
121 // We simply rely on the default global placement delete since a local placement delete would be
122 // ambiguous for some compilers
123 #pragma warning(push)
124 #pragma warning(disable : 4291)
125  void operator delete (void* ptr) { free(ptr); }
126 #pragma warning(pop)
127 
128  private:
129  // these can only be created by calling create()
130  RCString() {};
131  void* operator new (size_t objSize, size_t realSize) { return malloc(realSize); }
132 
133  int _size; // does NOT include trailing NUL byte.
134  // char[_size+1] array allocated past end of class
135  };
136 
137 };
138 
139 /* ======================= INLINED IMPLEMENTATIONS ========================== */
140 
141 namespace mongo {
142 
143  inline IntrusiveCounterUnsigned::IntrusiveCounterUnsigned():
144  counter(0) {
145  }
146 
147 };
A generic pointer type for function arguments.
Definition: goodies.h:176
This is an alternative base class to the above ones (will replace them eventually) ...
Definition: intrusive_counter.h:84
Definition: intrusive_counter.h:70
bool isShared() const
If false you have exclusive access to this object. This is useful for implementing COW...
Definition: intrusive_counter.h:87
Definition: intrusive_counter.h:55
This is an immutable reference-counted string.
Definition: intrusive_counter.h:111