Avoid `thread_local` on MacOS to prevent issues with hot reload
parent
a98d41f62b
commit
91833c852e
|
@ -40,6 +40,14 @@
|
||||||
|
|
||||||
#include <godot_cpp/godot.hpp>
|
#include <godot_cpp/godot.hpp>
|
||||||
|
|
||||||
|
#if defined(MACOS_ENABLED) && defined(HOT_RELOAD_ENABLED)
|
||||||
|
#include <mutex>
|
||||||
|
#define _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||||
|
#define _GODOT_CPP_THREAD_LOCAL
|
||||||
|
#else
|
||||||
|
#define _GODOT_CPP_THREAD_LOCAL thread_local
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
class ClassDB;
|
class ClassDB;
|
||||||
|
@ -58,11 +66,15 @@ class Wrapped {
|
||||||
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>>
|
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>>
|
||||||
friend _ALWAYS_INLINE_ void _pre_initialize();
|
friend _ALWAYS_INLINE_ void _pre_initialize();
|
||||||
|
|
||||||
thread_local static const StringName *_constructing_extension_class_name;
|
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||||
thread_local static const GDExtensionInstanceBindingCallbacks *_constructing_class_binding_callbacks;
|
static std::recursive_mutex _constructing_mutex;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_GODOT_CPP_THREAD_LOCAL static const StringName *_constructing_extension_class_name;
|
||||||
|
_GODOT_CPP_THREAD_LOCAL static const GDExtensionInstanceBindingCallbacks *_constructing_class_binding_callbacks;
|
||||||
|
|
||||||
#ifdef HOT_RELOAD_ENABLED
|
#ifdef HOT_RELOAD_ENABLED
|
||||||
thread_local static GDExtensionObjectPtr _constructing_recreate_owner;
|
_GODOT_CPP_THREAD_LOCAL static GDExtensionObjectPtr _constructing_recreate_owner;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -121,6 +133,9 @@ public:
|
||||||
|
|
||||||
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>>
|
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>>
|
||||||
_ALWAYS_INLINE_ void _pre_initialize() {
|
_ALWAYS_INLINE_ void _pre_initialize() {
|
||||||
|
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||||
|
Wrapped::_constructing_mutex.lock();
|
||||||
|
#endif
|
||||||
Wrapped::_set_construct_info<T>();
|
Wrapped::_set_construct_info<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,9 @@ private:
|
||||||
static GDExtensionClassInstancePtr _recreate_instance_func(void *data, GDExtensionObjectPtr obj) {
|
static GDExtensionClassInstancePtr _recreate_instance_func(void *data, GDExtensionObjectPtr obj) {
|
||||||
if constexpr (!std::is_abstract_v<T>) {
|
if constexpr (!std::is_abstract_v<T>) {
|
||||||
#ifdef HOT_RELOAD_ENABLED
|
#ifdef HOT_RELOAD_ENABLED
|
||||||
|
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||||
|
std::lock_guard<std::recursive_mutex> lk(Wrapped::_constructing_mutex);
|
||||||
|
#endif
|
||||||
Wrapped::_constructing_recreate_owner = obj;
|
Wrapped::_constructing_recreate_owner = obj;
|
||||||
T *new_instance = (T *)memalloc(sizeof(T));
|
T *new_instance = (T *)memalloc(sizeof(T));
|
||||||
memnew_placement(new_instance, T);
|
memnew_placement(new_instance, T);
|
||||||
|
|
|
@ -39,11 +39,16 @@
|
||||||
#include <godot_cpp/core/class_db.hpp>
|
#include <godot_cpp/core/class_db.hpp>
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
thread_local const StringName *Wrapped::_constructing_extension_class_name = nullptr;
|
|
||||||
thread_local const GDExtensionInstanceBindingCallbacks *Wrapped::_constructing_class_binding_callbacks = nullptr;
|
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||||
|
std::recursive_mutex Wrapped::_constructing_mutex;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_GODOT_CPP_THREAD_LOCAL const StringName *Wrapped::_constructing_extension_class_name = nullptr;
|
||||||
|
_GODOT_CPP_THREAD_LOCAL const GDExtensionInstanceBindingCallbacks *Wrapped::_constructing_class_binding_callbacks = nullptr;
|
||||||
|
|
||||||
#ifdef HOT_RELOAD_ENABLED
|
#ifdef HOT_RELOAD_ENABLED
|
||||||
thread_local GDExtensionObjectPtr Wrapped::_constructing_recreate_owner = nullptr;
|
_GODOT_CPP_THREAD_LOCAL GDExtensionObjectPtr Wrapped::_constructing_recreate_owner = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const StringName *Wrapped::_get_extension_class_name() {
|
const StringName *Wrapped::_get_extension_class_name() {
|
||||||
|
@ -51,6 +56,10 @@ const StringName *Wrapped::_get_extension_class_name() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wrapped::_postinitialize() {
|
void Wrapped::_postinitialize() {
|
||||||
|
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||||
|
Wrapped::_constructing_mutex.unlock();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Only send NOTIFICATION_POSTINITIALIZE for extension classes.
|
// Only send NOTIFICATION_POSTINITIALIZE for extension classes.
|
||||||
if (_is_extension_class()) {
|
if (_is_extension_class()) {
|
||||||
_notificationv(Object::NOTIFICATION_POSTINITIALIZE);
|
_notificationv(Object::NOTIFICATION_POSTINITIALIZE);
|
||||||
|
|
Loading…
Reference in New Issue