File tree Expand file tree Collapse file tree 5 files changed +29
-9
lines changed Expand file tree Collapse file tree 5 files changed +29
-9
lines changed Original file line number Diff line number Diff line change @@ -317,6 +317,21 @@ ref_if_nonzero() const {
317
317
return true ;
318
318
}
319
319
320
+ /* *
321
+ * Atomically decreases the reference count of this object if it is one.
322
+ * Do not use this. This exists only to implement a special case with the
323
+ * state cache.
324
+ * @return true if the reference count was decremented to zero.
325
+ */
326
+ INLINE bool ReferenceCount::
327
+ unref_if_one () const {
328
+ #ifdef _DEBUG
329
+ nassertr (test_ref_count_integrity (), 0 );
330
+ nassertr (_ref_count > 0 , 0 );
331
+ #endif
332
+ return (AtomicAdjust::compare_and_exchange (_ref_count, 1 , 0 ) == 1 );
333
+ }
334
+
320
335
/* *
321
336
* This global helper function will unref the given ReferenceCount object, and
322
337
* if the reference count reaches zero, automatically delete it. It can't be
Original file line number Diff line number Diff line change @@ -64,6 +64,7 @@ class EXPCL_PANDA_EXPRESS ReferenceCount : public MemoryBase {
64
64
INLINE void weak_unref ();
65
65
66
66
INLINE bool ref_if_nonzero () const ;
67
+ INLINE bool unref_if_one () const ;
67
68
68
69
protected:
69
70
bool do_test_ref_count_integrity () const ;
Original file line number Diff line number Diff line change @@ -215,14 +215,15 @@ garbage_collect() {
215
215
216
216
do {
217
217
RenderAttrib *attrib = (RenderAttrib *)_attribs->get_key (si);
218
- if (attrib->get_ref_count () == 1 ) {
218
+ if (attrib->unref_if_one () ) {
219
219
// This attrib has recently been unreffed to 1 (the one we added when
220
220
// we stored it in the cache). Now it's time to delete it. This is
221
221
// safe, because we're holding the _attribs_lock, so it's not possible
222
222
// for some other thread to find the attrib in the cache and ref it
223
- // while we're doing this.
223
+ // while we're doing this. Also, we've just made sure to unref it to 0,
224
+ // to ensure that another thread can't get it via a weak pointer.
224
225
attrib->release_new ();
225
- unref_delete ( attrib) ;
226
+ delete attrib;
226
227
227
228
// When we removed it from the hash map, it swapped the last element
228
229
// with the one we just removed. So the current index contains one we
Original file line number Diff line number Diff line change @@ -934,15 +934,17 @@ garbage_collect() {
934
934
}
935
935
}
936
936
937
- if (state->get_ref_count () == 1 ) {
937
+ if (state->unref_if_one () ) {
938
938
// This state has recently been unreffed to 1 (the one we added when
939
939
// we stored it in the cache). Now it's time to delete it. This is
940
940
// safe, because we're holding the _states_lock, so it's not possible
941
941
// for some other thread to find the state in the cache and ref it
942
- // while we're doing this.
942
+ // while we're doing this. Also, we've just made sure to unref it to 0,
943
+ // to ensure that another thread can't get it via a weak pointer.
944
+
943
945
state->release_new ();
944
946
state->remove_cache_pointers ();
945
- state->cache_unref ();
947
+ state->cache_unref_only ();
946
948
delete state;
947
949
948
950
// When we removed it from the hash map, it swapped the last element
Original file line number Diff line number Diff line change @@ -1204,15 +1204,16 @@ garbage_collect() {
1204
1204
}
1205
1205
}
1206
1206
1207
- if (state->get_ref_count () == 1 ) {
1207
+ if (state->unref_if_one () ) {
1208
1208
// This state has recently been unreffed to 1 (the one we added when
1209
1209
// we stored it in the cache). Now it's time to delete it. This is
1210
1210
// safe, because we're holding the _states_lock, so it's not possible
1211
1211
// for some other thread to find the state in the cache and ref it
1212
- // while we're doing this.
1212
+ // while we're doing this. Also, we've just made sure to unref it to 0,
1213
+ // to ensure that another thread can't get it via a weak pointer.
1213
1214
state->release_new ();
1214
1215
state->remove_cache_pointers ();
1215
- state->cache_unref ();
1216
+ state->cache_unref_only ();
1216
1217
delete state;
1217
1218
1218
1219
// When we removed it from the hash map, it swapped the last element
You can’t perform that action at this time.
0 commit comments