Skip to content

Commit f3abd0c

Browse files
committed
Refs #21664. Use atomic enumeration to control the instance state.
Signed-off-by: Miguel Company <[email protected]>
1 parent 5d718a3 commit f3abd0c

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

src/cpp/dynamic-types/TypeObjectFactory.cpp

+33-7
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <fastrtps/types/AnnotationDescriptor.h>
2626
#include <fastrtps/utils/md5.h>
2727
#include <fastdds/dds/log/Log.hpp>
28+
#include <atomic>
2829
#include <sstream>
2930

3031
namespace eprosima {
@@ -42,26 +43,51 @@ class TypeObjectFactoryReleaser
4243

4344
};
4445

46+
enum class TypeObjectFactoryInstanceState
47+
{
48+
NOT_CREATED = 0, // Instance has not been created
49+
CREATING = 1, // Instance is being created
50+
CREATED = 2, // Instance has been created
51+
DESTROYING = 3 // Instance is being destroyed
52+
};
53+
54+
static std::atomic<TypeObjectFactoryInstanceState> g_instance_state{TypeObjectFactoryInstanceState::NOT_CREATED};
4555
static TypeObjectFactoryReleaser s_releaser;
4656
static TypeObjectFactory* g_instance = nullptr;
57+
4758
TypeObjectFactory* TypeObjectFactory::get_instance()
4859
{
49-
if (g_instance == nullptr)
60+
TypeObjectFactoryInstanceState expected_state = TypeObjectFactoryInstanceState::NOT_CREATED;
61+
62+
// Wait until the instance is either created or destroyed
63+
while (!g_instance_state.compare_exchange_weak(expected_state, TypeObjectFactoryInstanceState::CREATING))
5064
{
51-
auto instance = new TypeObjectFactory();
52-
g_instance = instance;
53-
g_instance->create_builtin_annotations();
54-
return instance;
65+
// If it is already created, return it
66+
if (expected_state == TypeObjectFactoryInstanceState::CREATED)
67+
{
68+
return g_instance;
69+
}
70+
71+
// Prepare for retry
72+
expected_state = TypeObjectFactoryInstanceState::NOT_CREATED;
5573
}
56-
return g_instance;
74+
75+
auto instance = new TypeObjectFactory();
76+
instance->create_builtin_annotations();
77+
g_instance = instance;
78+
g_instance_state.store(TypeObjectFactoryInstanceState::CREATED);
79+
80+
return instance;
5781
}
5882

5983
ReturnCode_t TypeObjectFactory::delete_instance()
6084
{
61-
if (g_instance != nullptr)
85+
TypeObjectFactoryInstanceState expected_state = TypeObjectFactoryInstanceState::CREATED;
86+
if (g_instance_state.compare_exchange_strong(expected_state, TypeObjectFactoryInstanceState::DESTROYING))
6287
{
6388
delete g_instance;
6489
g_instance = nullptr;
90+
g_instance_state.store(TypeObjectFactoryInstanceState::NOT_CREATED);
6591
return ReturnCode_t::RETCODE_OK;
6692
}
6793
return ReturnCode_t::RETCODE_ERROR;

0 commit comments

Comments
 (0)