Panda3D
|
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 ©); 00048 INLINE void operator = (const CopyOnWriteObject ©); 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 ©); 00107 INLINE CopyOnWriteObj(const CopyOnWriteObj<Base> ©); 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 ©); 00141 INLINE CopyOnWriteObj1(const CopyOnWriteObj1<Base, Param1> ©); 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