diff --git a/rclc/include/rclc/executor.h b/rclc/include/rclc/executor.h index 1f685e81..c51b738c 100644 --- a/rclc/include/rclc/executor.h +++ b/rclc/include/rclc/executor.h @@ -981,6 +981,47 @@ rclc_executor_trigger_one( unsigned int size, void * obj); +/** + * Allocates an rclc_executor_t object and sets its values to zero. Can be + * used as an alternative to rclc_executor_get_zero_initialized_executor() if + * no stack allocation can or should be used. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[in] allocator the rcl_allocator_t to be used + * \return pointer to the executor (rclc_executor_t) + * \return NULL, if no memory could be allocated. + */ +RCLC_PUBLIC +rclc_executor_t * +rclc_alloc_zero_initialized_executor(const rcl_allocator_t * const allocator); + +/** + * De-allocates an rclc_executor_t object. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[inout] executor a heap-allocated rclc_executor_t + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +RCLC_PUBLIC +rcl_ret_t +rclc_executor_free( + rclc_executor_t * executor); + #if __cplusplus } #endif diff --git a/rclc/include/rclc/executor_handle.h b/rclc/include/rclc/executor_handle.h index 444a4ffd..bd2f826b 100644 --- a/rclc/include/rclc/executor_handle.h +++ b/rclc/include/rclc/executor_handle.h @@ -57,6 +57,9 @@ typedef enum ON_NEW_DATA, ALWAYS } rclc_executor_handle_invocation_t; +/** Can be used if the node cannot access defines.*/ +RCLC_PUBLIC extern const int32_t rclc_on_new_data; +RCLC_PUBLIC extern const int32_t rclc_always; /// Type definition for subscription callback function /// - incoming message diff --git a/rclc/include/rclc/init.h b/rclc/include/rclc/init.h index 832c9aab..16dab806 100644 --- a/rclc/include/rclc/init.h +++ b/rclc/include/rclc/init.h @@ -104,6 +104,152 @@ rcl_ret_t rclc_support_fini( rclc_support_t * support); +/** + * Allocates memory for an rclc_support_t object. + * Can be used if no stack allocation can or should be used. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[in] allocator the rcl_allocator_t to be used + * \return pointer to the support (rclc_support_t) + * \return NULL, if no memory could be allocated. + */ +RCLC_PUBLIC +rclc_support_t * +rclc_support_alloc(const rcl_allocator_t * const allocator); + +/** + * Return the pointer to the context member of struct support. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[inout] support an instance of type rclc_support_t + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +rcl_context_t * +rclc_get_context( + rclc_support_t * support); + +/** + * Return the pointer to the allocator member of struct support. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[inout] support an instance of type rclc_support_t + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +rcl_allocator_t * +rclc_get_allocator( + rclc_support_t * support); + +/** + * Return the pointer to the clock member of struct support. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[inout] support an instance of type rclc_support_t + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +rcl_clock_t * +rclc_get_clock( + rclc_support_t * support); + +/** + * De-allocates an rclc_support_t object. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[inout] support a heap-allocated rclc_support_t + * \param[in] allocator the rcl_allocator_t to be used + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +rcl_ret_t +rclc_support_free( + rclc_support_t * support, + const rcl_allocator_t * const allocator); + + +/** + * Allocates the rcl_allocator_t object and sets it to default values. + * Can be used as an alternative to rcl_get_default_allocator() if no + * stack allocation can or should be used. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \return pointer to the allocator (rcl_allocator_t) + * \return NULL, if no memory could be allocated. + */ +RCLC_PUBLIC +rcl_allocator_t * +rclc_allocator_alloc_default(); + +/** + * De-allocates an rcl_allocator_t object. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[inout] allocator a heap-allocated rcl_allocator_t + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +RCLC_PUBLIC +rcl_ret_t +rclc_allocator_free( + rcl_allocator_t * allocator); + + +/** Can be used if the node cannot access defines.*/ +RCLC_PUBLIC extern const int32_t rcl_ret_ok; +RCLC_PUBLIC extern const int32_t rcl_ret_error; +RCLC_PUBLIC extern const int32_t rcl_ret_timeout; +RCLC_PUBLIC extern const int32_t rcl_ret_unsupported; + #if __cplusplus } #endif diff --git a/rclc/include/rclc/node.h b/rclc/include/rclc/node.h index 9149a932..2bcce763 100644 --- a/rclc/include/rclc/node.h +++ b/rclc/include/rclc/node.h @@ -78,6 +78,48 @@ rclc_node_init_with_options( rclc_support_t * support, rcl_node_options_t * node_ops); +/** + * Allocates an rcl_node_t object and sets its values to zero. + * Can be used as an alternative to rcl_get_zero_initialized_node() if no + * stack allocation can or should be used. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[in] allocator the rcl_allocator_t to be used + * \return pointer to the node (rcl_node_t) + * \return NULL, if no memory could be allocated. + */ +RCLC_PUBLIC +rcl_node_t * +rclc_alloc_zero_initialized_node(const rcl_allocator_t * const allocator); + +/** + * De-allocates an rcl_node_t object. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[inout] node a heap-allocated rcl_node_t + * \param[in] allocator the rcl_allocator_t to be used + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +RCLC_PUBLIC +rcl_ret_t +rclc_node_free( + rcl_node_t * node, + const rcl_allocator_t * const allocator); #if __cplusplus } diff --git a/rclc/include/rclc/publisher.h b/rclc/include/rclc/publisher.h index 35815a21..bce9ad1d 100644 --- a/rclc/include/rclc/publisher.h +++ b/rclc/include/rclc/publisher.h @@ -108,6 +108,48 @@ rclc_publisher_init( const char * topic_name, const rmw_qos_profile_t * qos_profile); +/** + * Allocates memory for an rcl_publisher_t object. + * Can be used as if no stack allocation can or should be used. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[in] allocator the rcl_allocator_t to be used + * \return pointer to a publisher (rcl_publisher_t) + * \return NULL, if no memory could be allocated. + */ +RCLC_PUBLIC +rcl_publisher_t * +rclc_publisher_alloc( + const rcl_allocator_t * const allocator); + +/** + * De-allocates an rcl_publisher_t object. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[inout] publisher a heap-allocated rcl_publisher_t + * \param[in] allocator the rcl_allocator_t to be used + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +rcl_ret_t +rclc_publisher_free( + rcl_publisher_t * publisher, + const rcl_allocator_t * const allocator); + #if __cplusplus } #endif diff --git a/rclc/include/rclc/subscription.h b/rclc/include/rclc/subscription.h index cfa5ab48..24c330bd 100644 --- a/rclc/include/rclc/subscription.h +++ b/rclc/include/rclc/subscription.h @@ -107,6 +107,51 @@ rclc_subscription_init( const char * topic_name, const rmw_qos_profile_t * qos_profile); +/** + * Allocates an rcl_subscription_t object and sets its values to zero. + * Can be used as an alternative to rcl_get_zero_initialized_subscription() if no + * stack allocation can or should be used. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[in] allocator the rcl_allocator_t to be used + * \return pointer to the subscription (rcl_subscription_t) + * \return NULL, if no memory could be allocated. + */ +RCLC_PUBLIC +rcl_subscription_t * +rclc_alloc_zero_initialized_subscription( + const rcl_allocator_t * const allocator +); + +/** + * De-allocates an rcl_subscription_t object. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[inout] subscription a heap-allocated rcl_subscription_t + * \param[in] allocator the rcl_allocator_t to be used + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +RCLC_PUBLIC +rcl_ret_t +rclc_subscription_free( + rcl_subscription_t * subscription, + const rcl_allocator_t * const allocator); + #if __cplusplus } #endif diff --git a/rclc/include/rclc/timer.h b/rclc/include/rclc/timer.h index 60441529..0dd4c573 100644 --- a/rclc/include/rclc/timer.h +++ b/rclc/include/rclc/timer.h @@ -51,6 +51,51 @@ rclc_timer_init_default( const uint64_t timeout_ns, const rcl_timer_callback_t callback); +/** + * Allocates an rcl_timer_t object on the heap and sets its values to zero. + * Can be used as an alternative to rclc_timer_init_default() if no + * stack allocation can or should be used. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[in] allocator allocator for allocating memory + * \return pointer to the timer (rcl_timer_t) + * \return NULL, if no memory could be allocated. + */ +RCLC_PUBLIC +rcl_timer_t * +rclc_alloc_zero_initialized_timer( + const rcl_allocator_t * const allocator +); + +/** + * De-allocates an rcl_timer_t object. + * + * *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | No + * + * \param[inout] timer a heap-allocated rcl_timer_t + * \param[in] allocator the rcl_allocator_t to be used + * \return `RCL_RET_OK` if operation was successful + * \return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + */ +RCLC_PUBLIC +rcl_ret_t +rclc_timer_free( + rcl_timer_t * timer, + const rcl_allocator_t * const allocator); + #if __cplusplus } #endif diff --git a/rclc/src/rclc/executor.c b/rclc/src/rclc/executor.c index b91aa783..b5324a34 100644 --- a/rclc/src/rclc/executor.c +++ b/rclc/src/rclc/executor.c @@ -2119,3 +2119,23 @@ bool rclc_executor_trigger_always(rclc_executor_handle_t * handles, unsigned int RCLC_UNUSED(obj); return true; } + +rclc_executor_t * +rclc_alloc_zero_initialized_executor(const rcl_allocator_t * const allocator) +{ + rclc_executor_t * executor = (rclc_executor_t *) + allocator->allocate(sizeof(rclc_executor_t), allocator->state); + RCL_CHECK_FOR_NULL_WITH_MSG( + executor, "executor is a null pointer", return executor); + *executor = rclc_executor_get_zero_initialized_executor(); + return executor; +} + +rcl_ret_t +rclc_executor_free(rclc_executor_t * executor) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + executor, "executor is a null pointer", return RCL_RET_INVALID_ARGUMENT); + executor->allocator->deallocate(executor, executor->allocator->state); + return RCL_RET_OK; +} diff --git a/rclc/src/rclc/executor_handle.c b/rclc/src/rclc/executor_handle.c index dad84006..0af7bdee 100644 --- a/rclc/src/rclc/executor_handle.c +++ b/rclc/src/rclc/executor_handle.c @@ -19,6 +19,8 @@ #include #include +const int32_t rclc_on_new_data = ON_NEW_DATA; +const int32_t rclc_always = ALWAYS; // initialization of handle_counters object rcl_ret_t diff --git a/rclc/src/rclc/init.c b/rclc/src/rclc/init.c index 2c0174b9..095c1d29 100644 --- a/rclc/src/rclc/init.c +++ b/rclc/src/rclc/init.c @@ -22,6 +22,8 @@ #include #include +#include + rcl_ret_t rclc_support_init( rclc_support_t * support, @@ -105,3 +107,74 @@ rclc_support_fini(rclc_support_t * support) } return result; } + +rclc_support_t * +rclc_support_alloc(const rcl_allocator_t * const allocator) +{ + rclc_support_t * support = (rclc_support_t *) + allocator->allocate(sizeof(rclc_support_t), allocator->state); + RCL_CHECK_FOR_NULL_WITH_MSG( + support, "support is a null pointer", return support); + return support; +} + +rcl_ret_t +rclc_support_free(rclc_support_t * support, const rcl_allocator_t * const allocator) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + support, "support is a null pointer", return RCL_RET_INVALID_ARGUMENT); + allocator->deallocate(support, allocator->state); + return RCL_RET_OK; +} + + +rcl_context_t * +rclc_get_context(rclc_support_t * support) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + support, "support is a null pointer", return (rcl_context_t *) NULL); + return &(support->context); +} + +rcl_allocator_t * +rclc_get_allocator(rclc_support_t * support) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + support, "support is a null pointer", return (rcl_allocator_t *) NULL); + return support->allocator; +} + +rcl_clock_t * +rclc_get_clock(rclc_support_t * support) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + support, "support is a null pointer", return (rcl_clock_t *) NULL); + return &(support->clock); +} + +rcl_allocator_t * +rclc_allocator_alloc_default() +{ + rcl_allocator_t allocator_stack = rcl_get_default_allocator(); + rcl_allocator_t * allocator = (rcl_allocator_t *) + allocator_stack.allocate(sizeof(rcutils_allocator_t), allocator_stack.state); + RCL_CHECK_FOR_NULL_WITH_MSG( + allocator, "allocator is a null pointer", return allocator); + memcpy(allocator, &allocator_stack, sizeof(rcl_allocator_t)); + return allocator; +} + +rcl_ret_t +rclc_allocator_free(rcl_allocator_t * allocator) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + allocator, "allocator is a null pointer", return RCL_RET_INVALID_ARGUMENT); + allocator->deallocate(allocator, allocator->state); + return RCL_RET_OK; +} + + +const int32_t rcl_ret_ok = RCL_RET_OK; +const int32_t rcl_ret_error = RCL_RET_ERROR; +const int32_t rcl_ret_timeout = RCL_RET_TIMEOUT; +const int32_t rcl_ret_unsupported = RCL_RET_UNSUPPORTED; diff --git a/rclc/src/rclc/node.c b/rclc/src/rclc/node.c index 283777ef..bd64453f 100644 --- a/rclc/src/rclc/node.c +++ b/rclc/src/rclc/node.c @@ -19,6 +19,8 @@ #include #include +#include + rcl_ret_t rclc_node_init_default( rcl_node_t * node, @@ -82,3 +84,23 @@ rclc_node_init_with_options( } return rc; } + +rcl_node_t * +rclc_alloc_zero_initialized_node(const rcl_allocator_t * const allocator) +{ + rcl_node_t * node = (rcl_node_t *) + allocator->allocate(sizeof(rcl_node_t), allocator->state); + RCL_CHECK_FOR_NULL_WITH_MSG( + node, "node is a null pointer", return node); + *node = rcl_get_zero_initialized_node(); + return node; +} + +rcl_ret_t +rclc_node_free(rcl_node_t * node, const rcl_allocator_t * const allocator) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + node, "node is a null pointer", return RCL_RET_INVALID_ARGUMENT); + allocator->deallocate(node, allocator->state); + return RCL_RET_OK; +} diff --git a/rclc/src/rclc/publisher.c b/rclc/src/rclc/publisher.c index d53f5a27..d186461d 100644 --- a/rclc/src/rclc/publisher.c +++ b/rclc/src/rclc/publisher.c @@ -20,6 +20,8 @@ #include #include +#include + rcl_ret_t rclc_publisher_init_default( rcl_publisher_t * publisher, @@ -77,3 +79,24 @@ rclc_publisher_init( } return rc; } + +RCLC_PUBLIC +rcl_publisher_t * +rclc_publisher_alloc(const rcl_allocator_t * const allocator) +{ + rcl_publisher_t * publisher = (rcl_publisher_t *) + allocator->allocate(sizeof(rcl_publisher_t), allocator->state); + RCL_CHECK_FOR_NULL_WITH_MSG( + publisher, "publisher is a null pointer", return publisher); + return publisher; +} + +rcl_ret_t +rclc_publisher_free( + rcl_publisher_t * publisher, const rcl_allocator_t * const allocator) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + publisher, "publisher is a null pointer", return RCL_RET_INVALID_ARGUMENT); + allocator->deallocate(publisher, allocator->state); + return RCL_RET_OK; +} diff --git a/rclc/src/rclc/subscription.c b/rclc/src/rclc/subscription.c index af592543..e000e550 100644 --- a/rclc/src/rclc/subscription.c +++ b/rclc/src/rclc/subscription.c @@ -20,6 +20,8 @@ #include #include +#include + rcl_ret_t rclc_subscription_init_default( rcl_subscription_t * subscription, @@ -77,3 +79,24 @@ rclc_subscription_init( } return rc; } + +rcl_subscription_t * +rclc_alloc_zero_initialized_subscription(const rcl_allocator_t * const allocator) +{ + rcl_subscription_t * subscription = (rcl_subscription_t *) + allocator->allocate(sizeof(rcl_subscription_t), allocator->state); + RCL_CHECK_FOR_NULL_WITH_MSG( + subscription, "subscription is a null pointer", return subscription); + *subscription = rcl_get_zero_initialized_subscription(); + return subscription; +} + +rcl_ret_t +rclc_subscription_free( + rcl_subscription_t * subscription, const rcl_allocator_t * const allocator) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + subscription, "subscription is a null pointer", return RCL_RET_INVALID_ARGUMENT); + allocator->deallocate(subscription, allocator->state); + return RCL_RET_OK; +} diff --git a/rclc/src/rclc/timer.c b/rclc/src/rclc/timer.c index f480f9e6..cfbfd8fa 100644 --- a/rclc/src/rclc/timer.c +++ b/rclc/src/rclc/timer.c @@ -46,3 +46,23 @@ rclc_timer_init_default( } return rc; } + +rcl_timer_t * +rclc_alloc_zero_initialized_timer(const rcl_allocator_t * const allocator) +{ + rcl_timer_t * timer = (rcl_timer_t *) + allocator->allocate(sizeof(rcl_timer_t), allocator->state); + RCL_CHECK_FOR_NULL_WITH_MSG( + timer, "timer is a null pointer", return timer); + *timer = rcl_get_zero_initialized_timer(); + return timer; +} + +rcl_ret_t +rclc_timer_free(rcl_timer_t * timer, const rcl_allocator_t * const allocator) +{ + RCL_CHECK_FOR_NULL_WITH_MSG( + timer, "timer is a null pointer", return RCL_RET_INVALID_ARGUMENT); + allocator->deallocate(timer, allocator->state); + return RCL_RET_OK; +} diff --git a/rclc/test/rclc/test_executor.cpp b/rclc/test/rclc/test_executor.cpp index 86346f49..fdf0b8e1 100644 --- a/rclc/test/rclc/test_executor.cpp +++ b/rclc/test/rclc/test_executor.cpp @@ -2804,3 +2804,14 @@ TEST_F(TestDefaultExecutor, executor_test_remove_guard_condition) { rc = rclc_executor_fini(&executor); EXPECT_EQ(RCL_RET_OK, rc) << rcl_get_error_string().str; } + +TEST(TestDefaultExecutor, rclc_alloc_zero_initialized_executor) { + // test heap allocation and freeing + const rcl_allocator_t allocator = rcl_get_default_allocator(); + rclc_executor_t * executor = rclc_alloc_zero_initialized_executor(&allocator); + EXPECT_NE(nullptr, executor); + rcl_ret_t rc = rclc_executor_fini(executor); + EXPECT_EQ(RCL_RET_OK, rc); + rclc_executor_free(executor); + executor = nullptr; +} \ No newline at end of file diff --git a/rclc/test/rclc/test_init.cpp b/rclc/test/rclc/test_init.cpp index db8cac6d..6e344fd5 100644 --- a/rclc/test/rclc/test_init.cpp +++ b/rclc/test/rclc/test_init.cpp @@ -84,3 +84,36 @@ TEST(Test, rclc_support_fini) { EXPECT_EQ(RCL_RET_ERROR, rc); rcutils_reset_error(); } + +TEST(Test, rclc_support_alloc) { + // test heap allocation and freeing + rcl_allocator_t allocator = rcl_get_default_allocator(); + rclc_support_t * support = rclc_support_alloc(&allocator); + EXPECT_NE(nullptr, support); + rcl_ret_t rc = rclc_support_free(support, &allocator); + EXPECT_EQ(RCL_RET_OK, rc); + support = nullptr; +} + +TEST(Test, rclc_get_context) { + rclc_support_t support; + rcl_allocator_t allocator = rcl_get_default_allocator(); + rcl_ret_t rc = rclc_support_init(&support, 0, nullptr, &allocator); + EXPECT_EQ(RCL_RET_OK, rc); + + rcl_context_t *context = rclc_get_context(&support); + EXPECT_NE(nullptr, context); + EXPECT_TRUE(rcl_context_is_valid(context)); + + rc = rclc_support_fini(&support); + EXPECT_EQ(RCL_RET_OK, rc); +} + +TEST(Test, rclc_allocator_alloc_default) { + // test heap allocation and freeing + rcl_allocator_t * allocator = rclc_allocator_alloc_default(); + EXPECT_NE(nullptr, allocator); + rcl_ret_t rc = rclc_allocator_free(allocator); + EXPECT_EQ(RCL_RET_OK, rc); + allocator = nullptr; +} diff --git a/rclc/test/rclc/test_node.cpp b/rclc/test/rclc/test_node.cpp index 7dfcd01d..92d7881d 100644 --- a/rclc/test/rclc/test_node.cpp +++ b/rclc/test/rclc/test_node.cpp @@ -113,3 +113,13 @@ TEST(Test, rclc_node_init_with_options) { rc = rclc_support_fini(&support); EXPECT_EQ(RCL_RET_OK, rc); } + +TEST(Test, rclc_alloc_zero_initialized_node) { + // test heap allocation and freeing + const rcl_allocator_t allocator = rcl_get_default_allocator(); + rcl_node_t * node = rclc_alloc_zero_initialized_node(&allocator); + EXPECT_NE(nullptr, node); + rcl_ret_t rc = rclc_node_free(node, &allocator); + EXPECT_EQ(RCL_RET_OK, rc); + node = nullptr; +} \ No newline at end of file diff --git a/rclc/test/rclc/test_publisher.cpp b/rclc/test/rclc/test_publisher.cpp index c9faabb5..4697f624 100644 --- a/rclc/test/rclc/test_publisher.cpp +++ b/rclc/test/rclc/test_publisher.cpp @@ -154,3 +154,13 @@ TEST(Test, rclc_publisher_init_qos) { rc = rclc_support_fini(&support); EXPECT_EQ(RCL_RET_OK, rc); } + +TEST(Test, rclc_publisher_alloc) { + // test heap allocation and freeing + const rcl_allocator_t allocator = rcl_get_default_allocator(); + rcl_publisher_t * publisher = rclc_publisher_alloc(&allocator); + EXPECT_NE(nullptr, publisher); + rcl_ret_t rc = rclc_publisher_free(publisher, &allocator); + EXPECT_EQ(RCL_RET_OK, rc); + publisher = nullptr; +} \ No newline at end of file diff --git a/rclc/test/rclc/test_subscription.cpp b/rclc/test/rclc/test_subscription.cpp index 45723752..a1ffa33e 100644 --- a/rclc/test/rclc/test_subscription.cpp +++ b/rclc/test/rclc/test_subscription.cpp @@ -151,3 +151,13 @@ TEST(Test, rclc_subscription_init_qos) { rc = rclc_support_fini(&support); EXPECT_EQ(RCL_RET_OK, rc); } + +TEST(Test, rclc_alloc_zero_initialized_subscription) { + // test heap allocation and freeing + const rcl_allocator_t allocator = rcl_get_default_allocator(); + rcl_subscription_t * subscription = rclc_alloc_zero_initialized_subscription(&allocator); + EXPECT_NE(nullptr, subscription); + rcl_ret_t rc = rclc_subscription_free(subscription, &allocator); + EXPECT_EQ(RCL_RET_OK, rc); + subscription = nullptr; +} \ No newline at end of file diff --git a/rclc/test/rclc/test_timer.cpp b/rclc/test/rclc/test_timer.cpp index ce5c8671..d51c3f5e 100644 --- a/rclc/test/rclc/test_timer.cpp +++ b/rclc/test/rclc/test_timer.cpp @@ -56,3 +56,13 @@ TEST(Test, rclc_timer_init_default) { rc = rclc_support_fini(&support); EXPECT_EQ(RCL_RET_OK, rc); } + +TEST(Test, rclc_alloc_zero_initialized_timer) { + // test heap allocation and freeing + const rcl_allocator_t allocator = rcl_get_default_allocator(); + rcl_timer_t * timer = rclc_alloc_zero_initialized_timer(&allocator); + EXPECT_NE(nullptr, timer); + rcl_ret_t rc = rclc_timer_free(timer, &allocator); + EXPECT_EQ(RCL_RET_OK, rc); + timer = nullptr; +}