Browse Source

gobj: Make BufferContextChain thread-safe

rdb 10 months ago
parent
commit
8f4d0c8a66

+ 1 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -15086,6 +15086,7 @@ get_texture_memory_size(CLP(TextureContext) *gtc) {
 void CLP(GraphicsStateGuardian)::
 check_nonresident_texture(BufferContextChain &chain) {
 #if defined(SUPPORT_FIXED_FUNCTION) && !defined(OPENGLES)  // Residency queries not supported by OpenGL ES.
+  LightMutexHolder holder(chain._lock);
   size_t num_textures = chain.get_count();
   if (num_textures == 0) {
     return;

+ 4 - 1
panda/src/gobj/bufferContext.cxx

@@ -12,6 +12,7 @@
  */
 
 #include "bufferContext.h"
+#include "lightMutexHolder.h"
 
 TypeHandle BufferContext::_type_handle;
 
@@ -43,7 +44,8 @@ BufferContext::
 void BufferContext::
 set_owning_chain(BufferContextChain *chain) {
   if (chain != _owning_chain) {
-    if (_owning_chain != nullptr){
+    if (_owning_chain != nullptr) {
+      LightMutexHolder holder(_owning_chain->_lock);
       --(_owning_chain->_count);
       _owning_chain->adjust_bytes(-(int)_data_size_bytes);
       remove_from_list();
@@ -52,6 +54,7 @@ set_owning_chain(BufferContextChain *chain) {
     _owning_chain = chain;
 
     if (_owning_chain != nullptr) {
+      LightMutexHolder holder(_owning_chain->_lock);
       ++(_owning_chain->_count);
       _owning_chain->adjust_bytes((int)_data_size_bytes);
       insert_before(_owning_chain);

+ 7 - 0
panda/src/gobj/bufferContextChain.cxx

@@ -14,11 +14,15 @@
 #include "bufferContextChain.h"
 #include "bufferContext.h"
 #include "indent.h"
+#include "lightMutexHolder.h"
 
 /**
  * Returns the first BufferContext object stored in the tracker.  You can walk
  * through the entire list of objects stored on the tracker by calling
  * get_next() on each returned object, until the return value is NULL.
+ *
+ * This does not grab the lock; make sure you are holding the lock while
+ * iterating over the chain.
  */
 BufferContext *BufferContextChain::
 get_first() {
@@ -32,9 +36,11 @@ get_first() {
 
 /**
  * Moves all of the BufferContexts from the other tracker onto this one.
+ * The other chain must be locked.
  */
 void BufferContextChain::
 take_from(BufferContextChain &other) {
+  LightMutexHolder holder(_lock);
   _total_size += other._total_size;
   _count += other._count;
   other._total_size = 0;
@@ -55,6 +61,7 @@ take_from(BufferContextChain &other) {
  */
 void BufferContextChain::
 write(std::ostream &out, int indent_level) const {
+  LightMutexHolder holder(_lock);
   indent(out, indent_level)
     << _count << " objects, consuming " << _total_size << " bytes:\n";
 

+ 4 - 0
panda/src/gobj/bufferContextChain.h

@@ -16,6 +16,7 @@
 
 #include "pandabase.h"
 #include "linkedListNode.h"
+#include "lightMutex.h"
 
 class BufferContext;
 
@@ -47,6 +48,9 @@ private:
   size_t _total_size;
   int _count;
 
+public:
+  LightMutex _lock;
+
   friend class BufferContext;
 };
 

+ 1 - 0
panda/src/gobj/bufferResidencyTracker.cxx

@@ -117,6 +117,7 @@ write(std::ostream &out, int indent_level) const {
  */
 void BufferResidencyTracker::
 move_inactive(BufferContextChain &inactive, BufferContextChain &active) {
+  LightMutexHolder active_holder(active._lock);
   BufferContext *node = active.get_first();
   while (node != nullptr) {
     nassertv((node->_residency_state & S_active) != 0);