Pārlūkot izejas kodu

Merge branch 'release/1.9.x'

rdb 9 gadi atpakaļ
vecāks
revīzija
6f168446d0

+ 2 - 0
doc/ReleaseNotes

@@ -25,6 +25,8 @@ This issue fixes several bugs that were still found in 1.9.2.
 * Work around Cg bug generating invalid ASM for saturated tex loads
 * Work around Cg bug generating invalid ASM for saturated tex loads
 * Fix issues with certain Cg shader inputs in DX9
 * Fix issues with certain Cg shader inputs in DX9
 * Support uint8 index buffers in DX9
 * Support uint8 index buffers in DX9
+* Fix occasional frame lag when loading a big model asynchronously
+* Fix race condition reading string config var
 
 
 ------------------------  RELEASE 1.9.2  ------------------------
 ------------------------  RELEASE 1.9.2  ------------------------
 
 

+ 21 - 9
dtool/src/prc/configVariableFilename.cxx

@@ -19,16 +19,28 @@
  */
  */
 void ConfigVariableFilename::
 void ConfigVariableFilename::
 reload_cache() {
 reload_cache() {
-  nassertv(_core != (ConfigVariableCore *)NULL);
-  mark_cache_valid(_local_modified);
+  // NB. MSVC doesn't guarantee that this mutex is initialized in a
+  // thread-safe manner.  But chances are that the first time this is called
+  // is at static init time, when there is no risk of data races.
+  static MutexImpl lock;
+  lock.acquire();
 
 
-  const ConfigDeclaration *decl = _core->get_declaration(0);
-  const ConfigPage *page = decl->get_page();
+  // We check again for cache validity since another thread may have beaten
+  // us to the punch while we were waiting for the lock.
+  if (!is_cache_valid(_local_modified)) {
+    nassertv(_core != (ConfigVariableCore *)NULL);
 
 
-  Filename page_filename(page->get_name());
-  Filename page_dirname = page_filename.get_dirname();
-  ExecutionEnvironment::shadow_environment_variable("THIS_PRC_DIR", page_dirname.to_os_specific());
+    const ConfigDeclaration *decl = _core->get_declaration(0);
+    const ConfigPage *page = decl->get_page();
 
 
-  _cache = Filename::expand_from(decl->get_string_value());
-  ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
+    Filename page_filename(page->get_name());
+    Filename page_dirname = page_filename.get_dirname();
+    ExecutionEnvironment::shadow_environment_variable("THIS_PRC_DIR", page_dirname.to_os_specific());
+
+    _cache = Filename::expand_from(decl->get_string_value());
+    ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
+
+    mark_cache_valid(_local_modified);
+  }
+  lock.release();
 }
 }

+ 1 - 2
dtool/src/prc/configVariableString.I

@@ -127,8 +127,7 @@ INLINE const string &ConfigVariableString::
 get_value() const {
 get_value() const {
   TAU_PROFILE("const string &ConfigVariableString::get_value() const", " ", TAU_USER);
   TAU_PROFILE("const string &ConfigVariableString::get_value() const", " ", TAU_USER);
   if (!is_cache_valid(_local_modified)) {
   if (!is_cache_valid(_local_modified)) {
-    mark_cache_valid(((ConfigVariableString *)this)->_local_modified);
-    ((ConfigVariableString *)this)->_cache = get_string_value();
+    ((ConfigVariableString *)this)->reload_cache();
   }
   }
   return _cache;
   return _cache;
 }
 }

+ 21 - 0
dtool/src/prc/configVariableString.cxx

@@ -12,3 +12,24 @@
  */
  */
 
 
 #include "configVariableString.h"
 #include "configVariableString.h"
+
+/**
+ * Refreshes the variable's cached value.
+ */
+void ConfigVariableString::
+reload_cache() {
+  // NB. MSVC doesn't guarantee that this mutex is initialized in a
+  // thread-safe manner.  But chances are that the first time this is called
+  // is at static init time, when there is no risk of data races.
+  static MutexImpl lock;
+  lock.acquire();
+
+  // We check again for cache validity since another thread may have beaten
+  // us to the punch while we were waiting for the lock.
+  if (!is_cache_valid(_local_modified)) {
+    _cache = get_string_value();
+    mark_cache_valid(_local_modified);
+  }
+
+  lock.release();
+}

+ 3 - 0
dtool/src/prc/configVariableString.h

@@ -49,6 +49,9 @@ PUBLISHED:
   INLINE string get_word(size_t n) const;
   INLINE string get_word(size_t n) const;
   INLINE void set_word(size_t n, const string &value);
   INLINE void set_word(size_t n, const string &value);
 
 
+private:
+  void reload_cache();
+
 private:
 private:
   AtomicAdjust::Integer _local_modified;
   AtomicAdjust::Integer _local_modified;
   string _cache;
   string _cache;

+ 12 - 1
panda/src/putil/bamCache.cxx

@@ -310,13 +310,24 @@ emergency_read_only() {
  */
  */
 void BamCache::
 void BamCache::
 consider_flush_index() {
 consider_flush_index() {
-  ReMutexHolder holder(_lock);
+#if defined(HAVE_THREADS) || defined(DEBUG_THREADS)
+  if (!_lock.try_acquire()) {
+    // If we can't grab the lock, no big deal.  We don't want to hold up
+    // the frame waiting for a cache operation.  We can try again later.
+    return;
+  }
+#endif
+
   if (_index_stale_since != 0) {
   if (_index_stale_since != 0) {
     int elapsed = (int)time(NULL) - (int)_index_stale_since;
     int elapsed = (int)time(NULL) - (int)_index_stale_since;
     if (elapsed > _flush_time) {
     if (elapsed > _flush_time) {
       flush_index();
       flush_index();
     }
     }
   }
   }
+
+#if defined(HAVE_THREADS) || defined(DEBUG_THREADS)
+  _lock.release();
+#endif
 }
 }
 
 
 /**
 /**