Panda3D

copyOnWriteObject.h

00001 // Filename: copyOnWriteObject.h
00002 // Created by:  drose (09Apr07)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef COPYONWRITEOBJECT_H
00016 #define COPYONWRITEOBJECT_H
00017 
00018 #include "pandabase.h"
00019 
00020 #include "cachedTypedWritableReferenceCount.h"
00021 #include "pmutex.h"
00022 #include "conditionVar.h"
00023 #include "mutexHolder.h"
00024 
00025 // Should we implement full thread protection for CopyOnWritePointer?
00026 // If we can be assured that no other thread will interrupt while a
00027 // write pointer is held, we don't need thread protection.
00028 
00029 // Nowadays, this is the same thing as asking if HAVE_THREADS is
00030 // defined.  Maybe we'll just replace COW_THREADED with HAVE_THREADS
00031 // in the future.
00032 #ifdef HAVE_THREADS
00033   #define COW_THREADED 1
00034 #else
00035   #undef COW_THREADED
00036 #endif
00037 
00038 ////////////////////////////////////////////////////////////////////
00039 //       Class : CopyOnWriteObject
00040 // Description : This base class provides basic reference counting,
00041 //               but also can be used with a CopyOnWritePointer to
00042 //               provide get_read_pointer() and get_write_pointer().
00043 ////////////////////////////////////////////////////////////////////
00044 class EXPCL_PANDA_PUTIL CopyOnWriteObject : public CachedTypedWritableReferenceCount {
00045 public:
00046   INLINE CopyOnWriteObject();
00047   INLINE CopyOnWriteObject(const CopyOnWriteObject &copy);
00048   INLINE void operator = (const CopyOnWriteObject &copy);
00049 
00050 PUBLISHED:
00051 #ifdef COW_THREADED
00052   virtual bool unref() const;
00053   INLINE void cache_ref() const;
00054 #endif  // COW_THREADED
00055 
00056 protected:
00057   virtual PT(CopyOnWriteObject) make_cow_copy()=0;
00058 
00059 private:
00060 #ifdef COW_THREADED
00061   enum LockStatus {
00062     LS_unlocked,
00063     LS_locked_read,
00064     LS_locked_write,
00065   };
00066   Mutex _lock_mutex;
00067   ConditionVar _lock_cvar;
00068   LockStatus _lock_status;
00069   Thread *_locking_thread;
00070 #endif  // COW_THREADED
00071 
00072 public:
00073   virtual TypeHandle get_type() const {
00074     return get_class_type();
00075   }
00076   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00077 
00078 PUBLISHED:
00079   static TypeHandle get_class_type() {
00080     return _type_handle;
00081   }
00082 
00083 public:
00084   static void init_type() {
00085     CachedTypedWritableReferenceCount::init_type();
00086     register_type(_type_handle, "CopyOnWriteObject",
00087                   CachedTypedWritableReferenceCount::get_class_type());
00088   }
00089 
00090 private:
00091   static TypeHandle _type_handle;
00092 
00093   friend class CopyOnWritePointer;
00094 };
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //       Class : CopyOnWriteObj
00098 // Description : This is similar to RefCountObj, but it implements a
00099 //               CopyOnWriteObject inheritance instead of a
00100 //               ReferenceCount inheritance.
00101 ////////////////////////////////////////////////////////////////////
00102 template<class Base>
00103 class CopyOnWriteObj : public CopyOnWriteObject, public Base {
00104 public:
00105   INLINE CopyOnWriteObj();
00106   INLINE CopyOnWriteObj(const Base &copy);
00107   INLINE CopyOnWriteObj(const CopyOnWriteObj<Base> &copy);
00108   ALLOC_DELETED_CHAIN(CopyOnWriteObj<Base>);
00109 
00110 protected:
00111   virtual PT(CopyOnWriteObject) make_cow_copy();
00112 
00113 public:
00114   virtual TypeHandle get_type() const {
00115     return get_class_type();
00116   }
00117   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00118 
00119 PUBLISHED:
00120   static TypeHandle get_class_type() {
00121     return _type_handle;
00122   }
00123 
00124 public:
00125   static void init_type();
00126 
00127 private:
00128   static TypeHandle _type_handle;
00129 };
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //       Class : CopyOnWriteObj1
00133 // Description : For objects (e.g. pvectors) whose constructor
00134 //               takes a single parameter.
00135 ////////////////////////////////////////////////////////////////////
00136 template<class Base, class Param1>
00137 class CopyOnWriteObj1 : public CopyOnWriteObject, public Base {
00138 public:
00139   INLINE CopyOnWriteObj1(Param1 p1);
00140   INLINE CopyOnWriteObj1(const Base &copy);
00141   INLINE CopyOnWriteObj1(const CopyOnWriteObj1<Base, Param1> &copy);
00142 
00143   typedef CopyOnWriteObj1<Base, Param1> ThisClass;
00144   ALLOC_DELETED_CHAIN(ThisClass)
00145 
00146 protected:
00147   virtual PT(CopyOnWriteObject) make_cow_copy();
00148 
00149 public:
00150   virtual TypeHandle get_type() const {
00151     return get_class_type();
00152   }
00153   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00154 
00155 PUBLISHED:
00156   static TypeHandle get_class_type() {
00157     return _type_handle;
00158   }
00159 
00160 public:
00161   static void init_type();
00162 
00163 private:
00164   static TypeHandle _type_handle;
00165 };
00166 
00167 #include "copyOnWriteObject.I"
00168 
00169 #endif
 All Classes Functions Variables Enumerations