MongoDB C++ Driver  legacy-1.1.2
shared_buffer.h
1 
17 #pragma once
18 
19 #include <boost/intrusive_ptr.hpp>
20 
21 #include "mongo/platform/atomic_word.h"
22 
23 namespace mongo {
24 
25 class SharedBuffer {
26 public:
27  SharedBuffer() {}
28 
29  void swap(SharedBuffer& other) {
30  _holder.swap(other._holder);
31  }
32 
37  SharedBuffer out;
38  this->swap(out);
39  return out;
40  }
41 
42  static SharedBuffer allocate(size_t bytes) {
43  return takeOwnership(static_cast<char*>(malloc(sizeof(Holder) + bytes)));
44  }
45 
54  static SharedBuffer takeOwnership(char* holderPrefixedData) {
55  // Initialize the refcount to 1 so we don't need to increment it in the constructor
56  // (see private Holder* constructor below).
57  //
58  // TODO: Should dassert alignment of holderPrefixedData
59  // here if possible.
60  return SharedBuffer(new (holderPrefixedData) Holder(1U));
61  }
62 
63  char* get() const {
64  return _holder ? _holder->data() : NULL;
65  }
66 
67  class Holder {
68  public:
69  explicit Holder(AtomicUInt32::WordType initial = AtomicUInt32::WordType())
70  : _refCount(initial) {}
71 
72  // these are called automatically by boost::intrusive_ptr
73  friend void intrusive_ptr_add_ref(Holder* h) {
74  h->_refCount.fetchAndAdd(1);
75  }
76 
77  friend void intrusive_ptr_release(Holder* h) {
78  if (h->_refCount.subtractAndFetch(1) == 0) {
79  // We placement new'ed a Holder in takeOwnership above,
80  // so we must destroy the object here.
81  h->~Holder();
82  free(h);
83  }
84  }
85 
86  char* data() {
87  return reinterpret_cast<char*>(this + 1);
88  }
89 
90  const char* data() const {
91  return reinterpret_cast<const char*>(this + 1);
92  }
93 
94  private:
95  AtomicUInt32 _refCount;
96  };
97 
98 private:
99  explicit SharedBuffer(Holder* holder) : _holder(holder, /*add_ref=*/false) {
100  // NOTE: The 'false' above is because we have already initialized the Holder with a
101  // refcount of '1' in takeOwnership above. This avoids an atomic increment.
102  }
103 
104  boost::intrusive_ptr<Holder> _holder;
105 };
106 
107 inline void swap(SharedBuffer& one, SharedBuffer& two) {
108  one.swap(two);
109 }
110 }
Definition: shared_buffer.h:25
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
SharedBuffer moveFrom()
C++03 compatible way of writing std::move(someSharedBuffer)
Definition: shared_buffer.h:36
Definition: shared_buffer.h:67
static SharedBuffer takeOwnership(char *holderPrefixedData)
Given a pointer to a region of un-owned data, prefixed by sufficient space for a SharedBuffer::Holder...
Definition: shared_buffer.h:54