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

This commit is contained in:
rdb 2018-01-02 17:11:27 +01:00
parent 84bdce01f2
commit 92787264de
3 changed files with 16 additions and 15 deletions

View File

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

View File

@ -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::_start_clock_busy_wait)() = ClockObject::dummy_clock_wait;
void (*ClockObject::_stop_clock_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; TypeHandle ClockObject::_type_handle;
/** /**
* *
*/ */
ClockObject:: ClockObject::
ClockObject() : _ticks(get_class_type()) { ClockObject(Mode mode) : _ticks(get_class_type()), _mode(mode) {
_true_clock = TrueClock::get_global_ptr(); _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_short_time = _true_clock->get_short_time();
_start_long_time = _true_clock->get_long_time(); _start_long_time = _true_clock->get_long_time();
_actual_frame_time = 0.0; _actual_frame_time = 0.0;
@ -523,7 +518,7 @@ wait_until(double want_time) {
*/ */
void ClockObject:: void ClockObject::
make_global_clock() { make_global_clock() {
nassertv(_global_clock == (ClockObject *)NULL); nassertv(_global_clock == nullptr);
ConfigVariableEnum<ClockObject::Mode> clock_mode ConfigVariableEnum<ClockObject::Mode> clock_mode
("clock-mode", ClockObject::M_normal, ("clock-mode", ClockObject::M_normal,
@ -532,9 +527,13 @@ make_global_clock() {
"effects like simulated reduced frame rate. See " "effects like simulated reduced frame rate. See "
"ClockObject::set_mode().")); "ClockObject::set_mode()."));
_global_clock = new ClockObject; ClockObject *clock = new ClockObject(clock_mode);
_global_clock->set_mode(clock_mode); clock->local_object();
_global_clock->ref();
if (AtomicAdjust::compare_and_exchange_ptr(_global_clock, nullptr, clock) != nullptr) {
// Another thread beat us to it.
delete clock;
}
} }
/** /**

View File

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