-
Notifications
You must be signed in to change notification settings - Fork 117
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
Ensure compliant init options API implementations. #399
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ rmw_ret_t | |
rmw_init_options_init( | ||
const char * identifier, rmw_init_options_t * init_options, rcutils_allocator_t allocator) | ||
{ | ||
assert(identifier != NULL); | ||
RMW_CHECK_ARGUMENT_FOR_NULL(init_options, RMW_RET_INVALID_ARGUMENT); | ||
RCUTILS_CHECK_ALLOCATOR(&allocator, return RMW_RET_INVALID_ARGUMENT); | ||
if (NULL != init_options->implementation_identifier) { | ||
|
@@ -50,8 +51,13 @@ rmw_ret_t | |
rmw_init_options_copy( | ||
const char * identifier, const rmw_init_options_t * src, rmw_init_options_t * dst) | ||
{ | ||
assert(identifier != NULL); | ||
RMW_CHECK_ARGUMENT_FOR_NULL(src, RMW_RET_INVALID_ARGUMENT); | ||
RMW_CHECK_ARGUMENT_FOR_NULL(dst, RMW_RET_INVALID_ARGUMENT); | ||
if (NULL == src->implementation_identifier) { | ||
RMW_SET_ERROR_MSG("expected initialized dst"); | ||
return RMW_RET_INVALID_ARGUMENT; | ||
} | ||
RMW_CHECK_TYPE_IDENTIFIERS_MATCH( | ||
src, | ||
src->implementation_identifier, | ||
|
@@ -62,39 +68,47 @@ rmw_init_options_copy( | |
return RMW_RET_INVALID_ARGUMENT; | ||
} | ||
const rcutils_allocator_t * allocator = &src->allocator; | ||
rmw_ret_t ret = RMW_RET_OK; | ||
RCUTILS_CHECK_ALLOCATOR(allocator, return RMW_RET_INVALID_ARGUMENT); | ||
|
||
allocator->deallocate(dst->enclave, allocator->state); | ||
*dst = *src; | ||
dst->enclave = NULL; | ||
dst->security_options = rmw_get_zero_initialized_security_options(); | ||
|
||
dst->enclave = rcutils_strdup(src->enclave, *allocator); | ||
if (src->enclave && !dst->enclave) { | ||
ret = RMW_RET_BAD_ALLOC; | ||
goto fail; | ||
rmw_init_options_t tmp = *src; | ||
tmp.enclave = rcutils_strdup(tmp.enclave, *allocator); | ||
if (NULL != src->enclave && NULL == tmp.enclave) { | ||
return RMW_RET_BAD_ALLOC; | ||
} | ||
return rmw_security_options_copy(&src->security_options, allocator, &dst->security_options); | ||
fail: | ||
allocator->deallocate(dst->enclave, allocator->state); | ||
return ret; | ||
tmp.security_options = rmw_get_zero_initialized_security_options(); | ||
rmw_ret_t ret = | ||
rmw_security_options_copy(&src->security_options, allocator, &tmp.security_options); | ||
if (RMW_RET_OK != ret) { | ||
allocator->deallocate(tmp.enclave, allocator->state); | ||
return ret; | ||
} | ||
*dst = tmp; | ||
return RMW_RET_OK; | ||
} | ||
|
||
rmw_ret_t | ||
rmw_init_options_fini(const char * identifier, rmw_init_options_t * init_options) | ||
{ | ||
assert(identifier != NULL); | ||
RMW_CHECK_ARGUMENT_FOR_NULL(init_options, RMW_RET_INVALID_ARGUMENT); | ||
rcutils_allocator_t & allocator = init_options->allocator; | ||
RCUTILS_CHECK_ALLOCATOR(&allocator, return RMW_RET_INVALID_ARGUMENT); | ||
if (NULL == init_options->implementation_identifier) { | ||
RMW_SET_ERROR_MSG("expected initialized init_options"); | ||
return RMW_RET_INVALID_ARGUMENT; | ||
} | ||
RMW_CHECK_TYPE_IDENTIFIERS_MATCH( | ||
init_options, | ||
init_options->implementation_identifier, | ||
identifier, | ||
return RMW_RET_INCORRECT_RMW_IMPLEMENTATION); | ||
allocator.deallocate(init_options->enclave, allocator.state); | ||
rmw_security_options_fini(&init_options->security_options, &allocator); | ||
*init_options = rmw_get_zero_initialized_init_options(); | ||
return RMW_RET_OK; | ||
rcutils_allocator_t * allocator = &init_options->allocator; | ||
RCUTILS_CHECK_ALLOCATOR(allocator, return RMW_RET_INVALID_ARGUMENT); | ||
|
||
rmw_ret_t ret = rmw_security_options_fini(&init_options->security_options, allocator); | ||
if (RMW_RET_OK == ret) { | ||
allocator->deallocate(init_options->enclave, allocator->state); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this happen if security options failed to be deallocated? allocator->deallocate(init_options->enclave, allocator->state);
rmw_ret_t ret = rmw_security_options_fini(&init_options->security_options, allocator);
if (RMW_RET_OK == ret) {
*init_options = rmw_get_zero_initialized_init_options();
}
return ret; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, this is something I wasn't clear about in the API contract. I'm actively trying to ensure a failed finalization doesn't affect state. Alternatively, we could take the finalize-as-much-as-you-can approach AND prepare finalization functions for multiple calls on partially finalized state. WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, fini API contract has been updated. |
||
*init_options = rmw_get_zero_initialized_init_options(); | ||
} | ||
return ret; | ||
} | ||
|
||
} // namespace rmw_fastrtps_shared_cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without line 66-69, this function could perfectly work with a non-zero initialized
dst
AFAISThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, I prepared it for it. But it's lacking a finalization halfway through.
We can discuss guarantees later on and apply changes as needed.