00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00026
00027
00028
00029
00030
00031
00032 #ifdef HAVE_THREADS
00033 #define COW_THREADED 1
00034 #else
00035 #undef COW_THREADED
00036 #endif
00037
00038
00039
00040
00041
00042
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
00098
00099
00100
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
00133
00134
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