瀏覽代碼

putil: fix assertion when global clock is created on non-main thread

rdb 8 年之前
父節點
當前提交
92787264de
共有 3 個文件被更改,包括 16 次插入15 次删除
  1. 4 2
      panda/src/putil/clockObject.I
  2. 10 11
      panda/src/putil/clockObject.cxx
  3. 2 2
      panda/src/putil/clockObject.h

+ 4 - 2
panda/src/putil/clockObject.I

@@ -213,10 +213,12 @@ check_errors(Thread *current_thread) {
  */
 INLINE ClockObject *ClockObject::
 get_global_clock() {
-  if (_global_clock == (ClockObject *)NULL) {
+  ClockObject *clock = (ClockObject *)AtomicAdjust::get_ptr(_global_clock);
+  if (UNLIKELY(clock == nullptr)) {
     make_global_clock();
+    clock = (ClockObject *)_global_clock;
   }
-  return _global_clock;
+  return clock;
 }
 
 /**

+ 10 - 11
panda/src/putil/clockObject.cxx

@@ -21,21 +21,16 @@ void (*ClockObject::_start_clock_wait)() = ClockObject::dummy_clock_wait;
 void (*ClockObject::_start_clock_busy_wait)() = ClockObject::dummy_clock_wait;
 void (*ClockObject::_stop_clock_wait)() = ClockObject::dummy_clock_wait;
 
-ClockObject *ClockObject::_global_clock;
+AtomicAdjust::Pointer ClockObject::_global_clock = nullptr;
 TypeHandle ClockObject::_type_handle;
 
 /**
  *
  */
 ClockObject::
-ClockObject() : _ticks(get_class_type()) {
+ClockObject(Mode mode) : _ticks(get_class_type()), _mode(mode) {
   _true_clock = TrueClock::get_global_ptr();
 
-  // Each clock except for the application global clock is created in M_normal
-  // mode.  The application global clock is later reset to respect clock_mode,
-  // which comes from the Config.prc file.
-  _mode = M_normal;
-
   _start_short_time = _true_clock->get_short_time();
   _start_long_time = _true_clock->get_long_time();
   _actual_frame_time = 0.0;
@@ -523,7 +518,7 @@ wait_until(double want_time) {
  */
 void ClockObject::
 make_global_clock() {
-  nassertv(_global_clock == (ClockObject *)NULL);
+  nassertv(_global_clock == nullptr);
 
   ConfigVariableEnum<ClockObject::Mode> clock_mode
     ("clock-mode", ClockObject::M_normal,
@@ -532,9 +527,13 @@ make_global_clock() {
               "effects like simulated reduced frame rate.  See "
               "ClockObject::set_mode()."));
 
-  _global_clock = new ClockObject;
-  _global_clock->set_mode(clock_mode);
-  _global_clock->ref();
+  ClockObject *clock = new ClockObject(clock_mode);
+  clock->local_object();
+
+  if (AtomicAdjust::compare_and_exchange_ptr(_global_clock, nullptr, clock) != nullptr) {
+    // Another thread beat us to it.
+    delete clock;
+  }
 }
 
 /**

+ 2 - 2
panda/src/putil/clockObject.h

@@ -68,7 +68,7 @@ PUBLISHED:
     M_integer_limited,
   };
 
-  ClockObject();
+  ClockObject(Mode mode = M_normal);
   ClockObject(const ClockObject &copy);
   INLINE ~ClockObject();
 
@@ -172,7 +172,7 @@ private:
   typedef CycleDataWriter<CData> CDWriter;
   typedef CycleDataStageReader<CData> CDStageReader;
 
-  static ClockObject *_global_clock;
+  static AtomicAdjust::Pointer _global_clock;
 
 public:
   static TypeHandle get_class_type() {