Panda3D
copyOnWriteObject.h
1 // Filename: copyOnWriteObject.h
2 // Created by: drose (09Apr07)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef COPYONWRITEOBJECT_H
16 #define COPYONWRITEOBJECT_H
17 
18 #include "pandabase.h"
19 
20 #include "cachedTypedWritableReferenceCount.h"
21 #include "pmutex.h"
22 #include "conditionVar.h"
23 #include "mutexHolder.h"
24 
25 // Should we implement full thread protection for CopyOnWritePointer?
26 // If we can be assured that no other thread will interrupt while a
27 // write pointer is held, we don't need thread protection.
28 
29 // Nowadays, this is the same thing as asking if HAVE_THREADS is
30 // defined. Maybe we'll just replace COW_THREADED with HAVE_THREADS
31 // in the future.
32 #ifdef HAVE_THREADS
33  #define COW_THREADED 1
34 #else
35  #undef COW_THREADED
36 #endif
37 
38 ////////////////////////////////////////////////////////////////////
39 // Class : CopyOnWriteObject
40 // Description : This base class provides basic reference counting,
41 // but also can be used with a CopyOnWritePointer to
42 // provide get_read_pointer() and get_write_pointer().
43 ////////////////////////////////////////////////////////////////////
44 class EXPCL_PANDA_PUTIL CopyOnWriteObject : public CachedTypedWritableReferenceCount {
45 public:
46  INLINE CopyOnWriteObject();
47  INLINE CopyOnWriteObject(const CopyOnWriteObject &copy);
48  INLINE void operator = (const CopyOnWriteObject &copy);
49 
50 PUBLISHED:
51 #ifdef COW_THREADED
52  virtual bool unref() const;
53  INLINE void cache_ref() const;
54  INLINE bool cache_unref() const;
55 #endif // COW_THREADED
56 
57 protected:
58  virtual PT(CopyOnWriteObject) make_cow_copy()=0;
59 
60 private:
61 #ifdef COW_THREADED
62  enum LockStatus {
63  LS_unlocked,
64  LS_locked_read,
65  LS_locked_write,
66  };
67  Mutex _lock_mutex;
68  ConditionVar _lock_cvar;
69  LockStatus _lock_status;
70  Thread *_locking_thread;
71 #endif // COW_THREADED
72 
73 public:
74  virtual TypeHandle get_type() const {
75  return get_class_type();
76  }
77  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
78 
79 PUBLISHED:
80  static TypeHandle get_class_type() {
81  return _type_handle;
82  }
83 
84 public:
85  static void init_type() {
86  CachedTypedWritableReferenceCount::init_type();
87  register_type(_type_handle, "CopyOnWriteObject",
88  CachedTypedWritableReferenceCount::get_class_type());
89  }
90 
91 private:
92  static TypeHandle _type_handle;
93 
94  friend class CopyOnWritePointer;
95 };
96 
97 ////////////////////////////////////////////////////////////////////
98 // Class : CopyOnWriteObj
99 // Description : This is similar to RefCountObj, but it implements a
100 // CopyOnWriteObject inheritance instead of a
101 // ReferenceCount inheritance.
102 ////////////////////////////////////////////////////////////////////
103 template<class Base>
104 class CopyOnWriteObj : public CopyOnWriteObject, public Base {
105 public:
106  INLINE CopyOnWriteObj();
107  INLINE CopyOnWriteObj(const Base &copy);
108  INLINE CopyOnWriteObj(const CopyOnWriteObj<Base> &copy);
109  ALLOC_DELETED_CHAIN(CopyOnWriteObj<Base>);
110 
111 protected:
112  virtual PT(CopyOnWriteObject) make_cow_copy();
113 
114 public:
115  virtual TypeHandle get_type() const {
116  return get_class_type();
117  }
118  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
119 
120 PUBLISHED:
121  static TypeHandle get_class_type() {
122  return _type_handle;
123  }
124 
125 public:
126  static void init_type();
127 
128 private:
129  static TypeHandle _type_handle;
130 };
131 
132 ////////////////////////////////////////////////////////////////////
133 // Class : CopyOnWriteObj1
134 // Description : For objects (e.g. pvectors) whose constructor
135 // takes a single parameter.
136 ////////////////////////////////////////////////////////////////////
137 template<class Base, class Param1>
138 class CopyOnWriteObj1 : public CopyOnWriteObject, public Base {
139 public:
140  INLINE CopyOnWriteObj1(Param1 p1);
141  INLINE CopyOnWriteObj1(const Base &copy);
142  INLINE CopyOnWriteObj1(const CopyOnWriteObj1<Base, Param1> &copy);
143 
145  ALLOC_DELETED_CHAIN(ThisClass)
146 
147 protected:
148  virtual PT(CopyOnWriteObject) make_cow_copy();
149 
150 public:
151  virtual TypeHandle get_type() const {
152  return get_class_type();
153  }
154  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
155 
156 PUBLISHED:
157  static TypeHandle get_class_type() {
158  return _type_handle;
159  }
160 
161 public:
162  static void init_type();
163 
164 private:
165  static TypeHandle _type_handle;
166 };
167 
168 #include "copyOnWriteObject.I"
169 
170 #endif
For objects (e.g.
This is a special extension to ReferenceCount that includes dual reference counts: the standard refer...
A standard mutex, or mutual exclusion lock.
Definition: pmutex.h:44
A condition variable, usually used to communicate information about changing state to a thread that i...
Definition: conditionVar.h:47
bool cache_unref() const
Explicitly decrements the cache reference count and the normal reference count simultaneously.
void cache_ref() const
Explicitly increments the cache reference count and the normal reference count simultaneously.
This base class provides basic reference counting, but also can be used with a CopyOnWritePointer to ...
This safely stores the primary, owned pointer to a CopyOnWriteObject.
A thread; that is, a lightweight process.
Definition: thread.h:51
This is similar to RefCountObj, but it implements a CopyOnWriteObject inheritance instead of a Refere...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
virtual bool unref() const
Explicitly decrements the reference count.