Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce the concept of a domain lifecycle state. #1879

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions src/core/ddsc/include/dds/dds.h
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,51 @@ dds_create_domain(const dds_domainid_t domain, const char *config);
DDS_EXPORT dds_entity_t
dds_create_domain_with_rawconfig(const dds_domainid_t domain, const struct ddsi_config *config);

/// @brief Supported lifecycle states
/// @ingroup domain
typedef enum dds_domain_lifecycle{
DDS_DOMAIN_LIFECYCLE_INITIALISATION,
DDS_DOMAIN_LIFECYCLE_OPERATIONAL
} dds_domain_lifecycle_t;

/// @brief Function to indicate where we are in the domain's lifecycle
/// @note Domains starts out in the INITIALISATION
/// state. The only transition currently allowed is to set it OPERATIONAL.
/// The transition is currently only possible when applied to all domains via
/// the `DDS_CYCLONEDDS_HANDLE`.
///
/// @param[in] domain The domain entity for which to set the lifecycle state. Only accepts `DDS_CYCLONEDDS_HANDLE`.
/// @param[in] state The new state
/// @return a dds_retcode_t indicating success or failure
/// @retval DDS_RETCODE_OK transition was successful
/// @retval DDS_RETCODE_ERROR Internal error prevented the transition. Should not be possible.
/// @retval DDS_RETCODE_ILLEGAL_OPERATION handle refers to a non-domain entity
/// @retval DDS_RETCODE_PRECONDITION_NOT_MET attempt at an disallowed transition
/// @retval DDS_RETCODE_PRECONDITION_NOT_MET Cyclone DDS has not been initialised yet
DDS_EXPORT
dds_return_t dds_set_domain_lifecycle (
const dds_entity_t domain,
const enum dds_domain_lifecycle state);

/// @brief Get the status of the domain lifecycle
///
/// The domain life-cycle state represents the operational phase of the domain. Currently
/// the supported states are:
///
/// * Initialisation
/// * Operational
///
/// @param[in] domain The domain entity for which to get the life-cycle state for. Only accepts `DDS_CYCLONEDDS_HANDLE`.
/// @param[out] state The life-cycle state for the provided domain.
/// @return a dds_retcode_t indicating success or failure
/// @retval DDS_RETCODE_SUCCESS The state was successfully retrieved.
/// @retval DDS_RETCODE_BAD_PARAMETER An incorrect domain provided. Only supports `DDS_CYCLONEDDS_HANDLE` currently.
/// @retval DDS_RETCODE_PRECONDITION_NOT_MET An invalid pointer was provided for getting the state.
DDS_EXPORT
dds_return_t dds_get_domain_lifecycle(
const dds_entity_t domain,
enum dds_domain_lifecycle *state);

/**
* @brief Get entity parent.
* @ingroup entity
Expand Down
51 changes: 50 additions & 1 deletion src/core/ddsc/src/dds_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <string.h>

#include "dds/features.h"
#include "dds/ddsrt/cdtors.h"
#include "dds/ddsrt/process.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/hopscotch.h"
Expand All @@ -33,6 +34,7 @@
#include "dds__psmx.h"

static dds_return_t dds_domain_free (dds_entity *vdomain);
static enum dds_domain_lifecycle LIFECYCLE_STATE = DDS_DOMAIN_LIFECYCLE_INITIALISATION;

const struct dds_entity_deriver dds_entity_deriver_domain = {
.interrupt = dds_entity_deriver_dummy_interrupt,
Expand Down Expand Up @@ -439,6 +441,54 @@ void dds_write_set_batch (bool enable)
dds_entity_unpin_and_drop_ref (&dds_global.m_entity);
}

dds_return_t dds_set_domain_lifecycle(const dds_entity_t domain, const enum dds_domain_lifecycle state) {
dds_return_t result = DDS_RETCODE_ERROR;
if (dds_init () < 0) {
result = DDS_RETCODE_PRECONDITION_NOT_MET;
} else {
if (DDS_CYCLONEDDS_HANDLE == domain) {
switch (state) {
case DDS_DOMAIN_LIFECYCLE_OPERATIONAL:
// Only initialisation->operational is valid
if (LIFECYCLE_STATE == DDS_DOMAIN_LIFECYCLE_INITIALISATION) {
result = ddsrt_lock();
if (result == DDS_RETCODE_OK) {
LIFECYCLE_STATE = state;
} // else result is the error from ddsrt_lock()
} else { // only allow init->operational
result = DDS_RETCODE_PRECONDITION_NOT_MET;
}
break;
case DDS_DOMAIN_LIFECYCLE_INITIALISATION:
result = DDS_RETCODE_PRECONDITION_NOT_MET;
break;
default: // for MISRA compliance, no fall through :(
result = DDS_RETCODE_PRECONDITION_NOT_MET;
break;
}
} else {
result = DDS_RETCODE_ILLEGAL_OPERATION;
}
}
return result;
}

dds_return_t dds_get_domain_lifecycle(const dds_entity_t domain, enum dds_domain_lifecycle *state) {
dds_return_t result = DDS_RETCODE_OK;
if (NULL == state) {
result = DDS_RETCODE_PRECONDITION_NOT_MET;
} else {
if (DDS_CYCLONEDDS_HANDLE == domain) {
*state = LIFECYCLE_STATE;
} else {
result = DDS_RETCODE_BAD_PARAMETER;
}
}
return result;
}



#ifdef DDS_HAS_TYPE_DISCOVERY

dds_return_t dds_get_typeobj (dds_entity_t entity, const dds_typeid_t *type_id, dds_duration_t timeout, dds_typeobj_t **type_obj)
Expand Down Expand Up @@ -489,5 +539,4 @@ dds_return_t dds_free_typeobj (dds_typeobj_t *type_obj)
(void) type_obj;
return DDS_RETCODE_UNSUPPORTED;
}

#endif /* DDS_HAS_TYPE_DISCOVERY */
44 changes: 44 additions & 0 deletions src/core/ddsc/tests/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,47 @@ CU_Test(ddsc_domain_create, raw_config)
ddsrt_free (arg_raw.buf);
}

CU_Test(ddsc_domain_lifecycle, basic_transition)
{
dds_domain_lifecycle_t lifecycle_state = -1;
dds_return_t retval = dds_get_domain_lifecycle(DDS_CYCLONEDDS_HANDLE, &lifecycle_state);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_OK);
CU_ASSERT_EQUAL(lifecycle_state, DDS_DOMAIN_LIFECYCLE_INITIALISATION);

retval = dds_set_domain_lifecycle(DDS_CYCLONEDDS_HANDLE, DDS_DOMAIN_LIFECYCLE_OPERATIONAL);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_OK);
retval = dds_get_domain_lifecycle(DDS_CYCLONEDDS_HANDLE, &lifecycle_state);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_OK);
CU_ASSERT_EQUAL(lifecycle_state, DDS_DOMAIN_LIFECYCLE_OPERATIONAL);
}

CU_Test(ddsc_domain_lifecycle, invalid_transitions)
{
dds_domain_lifecycle_t lifecycle_state = -1;

// Null check, get
dds_return_t retval = dds_get_domain_lifecycle(DDS_CYCLONEDDS_HANDLE, NULL);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_PRECONDITION_NOT_MET);

// Invalid handle, get
retval = dds_get_domain_lifecycle(0, &lifecycle_state);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_BAD_PARAMETER);

// Invalid init->init transition
retval = dds_set_domain_lifecycle(DDS_CYCLONEDDS_HANDLE, DDS_DOMAIN_LIFECYCLE_INITIALISATION);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_PRECONDITION_NOT_MET);

// Invalid handle, set
retval = dds_set_domain_lifecycle(0, DDS_DOMAIN_LIFECYCLE_OPERATIONAL);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_ILLEGAL_OPERATION);

// Invalid operatational->init transition
retval = dds_set_domain_lifecycle(DDS_CYCLONEDDS_HANDLE, DDS_DOMAIN_LIFECYCLE_OPERATIONAL);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_OK);
retval = dds_set_domain_lifecycle(DDS_CYCLONEDDS_HANDLE, DDS_DOMAIN_LIFECYCLE_INITIALISATION);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_PRECONDITION_NOT_MET);

// Nonexistent state
retval = dds_set_domain_lifecycle(DDS_CYCLONEDDS_HANDLE, 3);
CU_ASSERT_EQUAL(retval, DDS_RETCODE_PRECONDITION_NOT_MET);
}
2 changes: 2 additions & 0 deletions src/core/xtests/symbol_export/symbol_export.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ int main (int argc, char **argv)
dds_create_participant (0, ptr, ptr);
dds_create_domain (0, ptr);
dds_create_domain_with_rawconfig (0, ptr);
dds_set_domain_lifecycle(0,0);
dds_get_domain_lifecycle(0,ptr);
dds_get_parent (1);
dds_get_participant (1);
dds_get_children (1, ptr, 0);
Expand Down
8 changes: 8 additions & 0 deletions src/ddsrt/include/dds/ddsrt/cdtors.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ void ddsrt_init(void);
* (when the reference count is 1) actually finalizes it.
*/
void ddsrt_fini(void);
///
/// @brief Lock the pooled memory allocator
///
dds_return_t ddsrt_lock(void);

/// @brief Unlock the pooled memory allocator
///
dds_return_t ddsrt_unlock(void);

/**
* @brief Get a pointer to the global 'init_mutex'
Expand Down
10 changes: 10 additions & 0 deletions src/ddsrt/src/cdtors.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ void ddsrt_fini (void)
}
}

dds_return_t ddsrt_lock (void) {
dds_return_t dds_result = DDS_RETCODE_OK;
return dds_result;
}

dds_return_t ddsrt_unlock (void) {
dds_return_t dds_result = DDS_RETCODE_OK;
return dds_result;
}

ddsrt_mutex_t *ddsrt_get_singleton_mutex(void)
{
return &init_mutex;
Expand Down
Loading