Skip to content

Commit

Permalink
Refs #21664. Use atomic enumeration to control the instance state.
Browse files Browse the repository at this point in the history
Signed-off-by: Miguel Company <[email protected]>
  • Loading branch information
MiguelCompany committed Sep 13, 2024
1 parent 5d718a3 commit f3abd0c
Showing 1 changed file with 33 additions and 7 deletions.
40 changes: 33 additions & 7 deletions src/cpp/dynamic-types/TypeObjectFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <fastrtps/types/AnnotationDescriptor.h>
#include <fastrtps/utils/md5.h>
#include <fastdds/dds/log/Log.hpp>
#include <atomic>
#include <sstream>

namespace eprosima {
Expand All @@ -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<TypeObjectFactoryInstanceState> 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;
Expand Down

0 comments on commit f3abd0c

Please sign in to comment.