diff --git a/src/cpp/dynamic-types/TypeObjectFactory.cpp b/src/cpp/dynamic-types/TypeObjectFactory.cpp index c5c6acc4868..351997c5117 100644 --- a/src/cpp/dynamic-types/TypeObjectFactory.cpp +++ b/src/cpp/dynamic-types/TypeObjectFactory.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include namespace eprosima { @@ -42,26 +43,51 @@ class TypeObjectFactoryReleaser }; +enum class TypeObjectFactoryInstanceState +{ + NOT_CREATED = 0, // Instance has not been created + CREATING = 1, // Instance is being created + CREATED = 2, // Instance has been created + DESTROYING = 3 // Instance is being destroyed +}; + +static std::atomic g_instance_state{TypeObjectFactoryInstanceState::NOT_CREATED}; static TypeObjectFactoryReleaser s_releaser; static TypeObjectFactory* g_instance = nullptr; + TypeObjectFactory* TypeObjectFactory::get_instance() { - if (g_instance == nullptr) + TypeObjectFactoryInstanceState expected_state = TypeObjectFactoryInstanceState::NOT_CREATED; + + // Wait until the instance is either created or destroyed + while (!g_instance_state.compare_exchange_weak(expected_state, TypeObjectFactoryInstanceState::CREATING)) { - auto instance = new TypeObjectFactory(); - g_instance = instance; - g_instance->create_builtin_annotations(); - return instance; + // If it is already created, return it + if (expected_state == TypeObjectFactoryInstanceState::CREATED) + { + return g_instance; + } + + // Prepare for retry + expected_state = TypeObjectFactoryInstanceState::NOT_CREATED; } - return g_instance; + + auto instance = new TypeObjectFactory(); + instance->create_builtin_annotations(); + g_instance = instance; + g_instance_state.store(TypeObjectFactoryInstanceState::CREATED); + + return instance; } ReturnCode_t TypeObjectFactory::delete_instance() { - if (g_instance != nullptr) + TypeObjectFactoryInstanceState expected_state = TypeObjectFactoryInstanceState::CREATED; + if (g_instance_state.compare_exchange_strong(expected_state, TypeObjectFactoryInstanceState::DESTROYING)) { delete g_instance; g_instance = nullptr; + g_instance_state.store(TypeObjectFactoryInstanceState::NOT_CREATED); return ReturnCode_t::RETCODE_OK; } return ReturnCode_t::RETCODE_ERROR;