MongoDB  2.1.1-pre-
intrusive_counter.h
00001 
00017 #pragma once
00018 
00019 #include <boost/intrusive_ptr.hpp>
00020 #include <boost/noncopyable.hpp>
00021 
00022 namespace mongo {
00023 
00024 /*
00025   IntrusiveCounter is a sharable implementation of a reference counter that
00026   objects can use to be compatible with boost::intrusive_ptr<>.
00027 
00028   Some objects that use IntrusiveCounter are immutable, and only have
00029   const methods.  This may require their pointers to be declared as
00030   intrusive_ptr<const ClassName> .  In order to be able to share pointers to
00031   these immutables, the methods associated with IntrusiveCounter are declared
00032   as const, and the counter itself is marked as mutable.
00033 
00034   IntrusiveCounter itself is abstract, allowing for multiple implementations.
00035   For example, IntrusiveCounterUnsigned uses ordinary unsigned integers for
00036   the reference count, and is good for situations where thread safety is not
00037   required.  For others, other implementations using atomic integers should
00038   be used.  For static objects, the implementations of addRef() and release()
00039   can be overridden to do nothing.
00040  */
00041     class IntrusiveCounter :
00042         boost::noncopyable {
00043     public:
00044         virtual ~IntrusiveCounter() {};
00045 
00046         // these are here for the boost intrusive_ptr<> class
00047         friend inline void intrusive_ptr_add_ref(const IntrusiveCounter *pIC) {
00048             pIC->addRef(); };
00049         friend inline void intrusive_ptr_release(const IntrusiveCounter *pIC) {
00050             pIC->release(); };
00051 
00052         virtual void addRef() const = 0;
00053         virtual void release() const = 0;
00054     };
00055 
00056     class IntrusiveCounterUnsigned :
00057         public IntrusiveCounter {
00058     public:
00059         // virtuals from IntrusiveCounter
00060         virtual void addRef() const;
00061         virtual void release() const;
00062 
00063         IntrusiveCounterUnsigned();
00064 
00065     private:
00066         mutable unsigned counter;
00067     };
00068 
00069 };
00070 
00071 /* ======================= INLINED IMPLEMENTATIONS ========================== */
00072 
00073 namespace mongo {
00074 
00075     inline IntrusiveCounterUnsigned::IntrusiveCounterUnsigned():
00076         counter(0) {
00077     }
00078 
00079 };