Browse Source

minor thread-safe fix

David Rose 19 years ago
parent
commit
1390d9ff22
2 changed files with 20 additions and 19 deletions
  1. 16 18
      panda/src/pgraph/pandaNode.cxx
  2. 4 1
      panda/src/pgraph/pandaNode.h

+ 16 - 18
panda/src/pgraph/pandaNode.cxx

@@ -3645,24 +3645,22 @@ check_bounds() const {
     // We'll need to get a fresh read pointer, since another thread
     // We'll need to get a fresh read pointer, since another thread
     // might already have modified the pointer on the object since we
     // might already have modified the pointer on the object since we
     // queried it.
     // queried it.
-    {
-      int pipeline_stage = _current_thread->get_pipeline_stage();
-      PandaNode::CDLockedStageReader fresh_cdata(_object->_cycler, pipeline_stage, _current_thread);
-      if (fresh_cdata->_last_update == fresh_cdata->_next_update) {
-        // What luck, some other thread has already freshened the
-        // cache for us.  Save the new pointer, and let the lock
-        // release itself.
-        ((PandaNodePipelineReader *)this)->_cdata = fresh_cdata;
-
-      } else {
-        // No, the cache is still stale.  We have to do the work of
-        // freshening it.
-        PandaNode::CDStageWriter cdataw = ((PandaNode *)_object)->update_bounds(pipeline_stage, fresh_cdata);
-        nassertv(cdataw->_last_update == cdataw->_next_update);
-        // As above, we save the new pointer, and then let the lock
-        // release itself.
-        ((PandaNodePipelineReader *)this)->_cdata = cdataw;
-      }
+    int pipeline_stage = _current_thread->get_pipeline_stage();
+    PandaNode::CDLockedStageReader fresh_cdata(_object->_cycler, pipeline_stage, _current_thread);
+    if (fresh_cdata->_last_update == fresh_cdata->_next_update) {
+      // What luck, some other thread has already freshened the
+      // cache for us.  Save the new pointer, and let the lock
+      // release itself.
+      ((PandaNodePipelineReader *)this)->_cdata = fresh_cdata;
+      
+    } else {
+      // No, the cache is still stale.  We have to do the work of
+      // freshening it.
+      PandaNode::CDStageWriter cdataw = ((PandaNode *)_object)->update_bounds(pipeline_stage, fresh_cdata);
+      nassertv(cdataw->_last_update == cdataw->_next_update);
+      // As above, we save the new pointer, and then let the lock
+      // release itself.
+      ((PandaNodePipelineReader *)this)->_cdata = cdataw;
     }
     }
   }
   }
 
 

+ 4 - 1
panda/src/pgraph/pandaNode.h

@@ -675,7 +675,10 @@ private:
   Thread *_current_thread;
   Thread *_current_thread;
 
 
 #ifdef DO_PIPELINING
 #ifdef DO_PIPELINING
-  CPT(PandaNode::CData) _cdata;
+  // We node_ref the CData pointer, so that if anyone makes changes to
+  // the PandaNode while we hold this pointer, it will force a
+  // copy--so that this object will remain unchanged (if out-of-date).
+  NCPT(PandaNode::CData) _cdata;
 #else
 #else
   const PandaNode::CData *_cdata;
   const PandaNode::CData *_cdata;
 #endif  // DO_PIPELINING
 #endif  // DO_PIPELINING