rmw_ret_t rmw_destroy_client(rmw_client_t * client) { if (!client) { RMW_SET_ERROR_MSG("client handle is null"); return RMW_RET_ERROR; } RMW_CHECK_TYPE_IDENTIFIERS_MATCH( client handle, client->implementation_identifier, opensplice_cpp_identifier, return RMW_RET_ERROR) OpenSpliceStaticClientInfo * client_info = static_cast<OpenSpliceStaticClientInfo *>(client->data); auto result = RMW_RET_OK; if (client_info) { auto response_datareader = client_info->response_datareader_; if (response_datareader) { auto read_condition = client_info->read_condition_; if (read_condition) { if (response_datareader->delete_readcondition(read_condition) != DDS::RETCODE_OK) { RMW_SET_ERROR_MSG("failed to delete readcondition"); result = RMW_RET_ERROR; } client_info->read_condition_ = nullptr; } } } else { RMW_SET_ERROR_MSG("client_info handle is null"); return RMW_RET_ERROR; } const service_type_support_callbacks_t * callbacks = static_cast<const service_type_support_callbacks_t *>(client_info->callbacks_); if (!callbacks) { RMW_SET_ERROR_MSG("callbacks handle is null"); return RMW_RET_ERROR; } const char * error_string = callbacks->destroy_requester(client_info->requester_, &rmw_free); if (error_string) { RMW_SET_ERROR_MSG((std::string("failed to destroy requester: ") + error_string).c_str()); return RMW_RET_ERROR; } if (client->service_name) { rmw_free(const_cast<char *>(client->service_name)); } rmw_free(client_info); rmw_client_free(client); return result; }
void __rmw_reset_error(rmw_error_state_t ** error_state_ptr_ptr) { rmw_error_state_t * error_state_ptr = *error_state_ptr_ptr; if (error_state_ptr_ptr) { if (error_state_ptr) { if (error_state_ptr->message) { // Cast const away to delete previously allocated memory. rmw_free((char *)error_state_ptr->message); } rmw_free(error_state_ptr); } } *error_state_ptr_ptr = NULL; }
rmw_guard_condition_t * create_guard_condition(const char * implementation_identifier) { rmw_guard_condition_t * guard_condition = rmw_guard_condition_allocate(); if (!guard_condition) { RMW_SET_ERROR_MSG("failed to allocate guard condition"); return NULL; } // Allocate memory for the DDSGuardCondition object. DDSGuardCondition * dds_guard_condition = nullptr; void * buf = rmw_allocate(sizeof(DDSGuardCondition)); if (!buf) { RMW_SET_ERROR_MSG("failed to allocate memory"); goto fail; } // Use a placement new to construct the DDSGuardCondition in the preallocated buffer. RMW_TRY_PLACEMENT_NEW(dds_guard_condition, buf, goto fail, DDSGuardCondition) buf = nullptr; // Only free the dds_guard_condition pointer; don't need the buf pointer anymore. guard_condition->implementation_identifier = implementation_identifier; guard_condition->data = dds_guard_condition; return guard_condition; fail: if (guard_condition) { rmw_guard_condition_free(guard_condition); } if (buf) { rmw_free(buf); } return NULL; }
void rmw_reset_error() { if (__rmw_error_state) { if (__rmw_error_state->message) { // Cast const away to delete previously allocated memory. rmw_free((char *)__rmw_error_state->message); } rmw_free(__rmw_error_state); } __rmw_error_state = NULL; if (__rmw_error_string) { rmw_free(__rmw_error_string); } __rmw_error_string = NULL; }
void __rmw_reset_error_string(char ** error_string_ptr) { char * error_string = *error_string_ptr; if (error_string) { if (error_string) { rmw_free(error_string); } } *error_string_ptr = NULL; }
void destroy_topic_names_and_types( rmw_topic_names_and_types_t * topic_names_and_types) { if (topic_names_and_types->topic_count) { for (size_t i = 0; i < topic_names_and_types->topic_count; ++i) { delete topic_names_and_types->topic_names[i]; delete topic_names_and_types->type_names[i]; topic_names_and_types->topic_names[i] = nullptr; topic_names_and_types->type_names[i] = nullptr; } if (topic_names_and_types->topic_names) { rmw_free(topic_names_and_types->topic_names); topic_names_and_types->topic_names = nullptr; } if (topic_names_and_types->type_names) { rmw_free(topic_names_and_types->type_names); topic_names_and_types->type_names = nullptr; } topic_names_and_types->topic_count = 0; } }
rmw_ret_t destroy_guard_condition(const char * implementation_identifier, rmw_guard_condition_t * guard_condition) { if (!guard_condition) { RMW_SET_ERROR_MSG("guard condition handle is null"); return RMW_RET_ERROR; } RMW_CHECK_TYPE_IDENTIFIERS_MATCH( guard condition handle, guard_condition->implementation_identifier, implementation_identifier, return RMW_RET_ERROR) auto result = RMW_RET_OK; RMW_TRY_DESTRUCTOR( static_cast<DDSGuardCondition *>(guard_condition->data)->~DDSGuardCondition(), DDSGuardCondition, result = RMW_RET_ERROR) rmw_free(guard_condition->data); rmw_guard_condition_free(guard_condition); return result; }
rmw_ret_t destroy_node(const char * implementation_identifier, rmw_node_t * node) { if (!node) { RMW_SET_ERROR_MSG("node handle is null"); return RMW_RET_ERROR; } RMW_CHECK_TYPE_IDENTIFIERS_MATCH( node handle, node->implementation_identifier, implementation_identifier, return RMW_RET_ERROR) DDSDomainParticipantFactory * dpf_ = DDSDomainParticipantFactory::get_instance(); if (!dpf_) { RMW_SET_ERROR_MSG("failed to get participant factory"); return RMW_RET_ERROR; } auto node_info = static_cast<ConnextNodeInfo *>(node->data); if (!node_info) { RMW_SET_ERROR_MSG("node info handle is null"); return RMW_RET_ERROR; } auto participant = static_cast<DDSDomainParticipant *>(node_info->participant); if (!participant) { RMW_SET_ERROR_MSG("participant handle is null"); } // This unregisters types and destroys topics which were shared between // publishers and subscribers and could not be cleaned up in the delete functions. if (participant->delete_contained_entities() != DDS::RETCODE_OK) { RMW_SET_ERROR_MSG("failed to delete contained entities of participant"); return RMW_RET_ERROR; } DDS_ReturnCode_t ret = dpf_->delete_participant(participant); if (ret != DDS_RETCODE_OK) { RMW_SET_ERROR_MSG("failed to delete participant"); return RMW_RET_ERROR; } if (node_info->publisher_listener) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( node_info->publisher_listener->~CustomPublisherListener(), CustomPublisherListener) rmw_free(node_info->publisher_listener); node_info->publisher_listener = nullptr; } if (node_info->subscriber_listener) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( node_info->subscriber_listener->~CustomSubscriberListener(), CustomSubscriberListener) rmw_free(node_info->subscriber_listener); node_info->subscriber_listener = nullptr; } if (node_info->graph_guard_condition) { rmw_ret_t ret = destroy_guard_condition(implementation_identifier, node_info->graph_guard_condition); if (ret != RMW_RET_OK) { RMW_SET_ERROR_MSG("failed to delete graph guard condition"); return RMW_RET_ERROR; } node_info->graph_guard_condition = nullptr; } rmw_free(node_info); node->data = nullptr; rmw_free(const_cast<char *>(node->name)); node->name = nullptr; rmw_node_free(node); return RMW_RET_OK; }
rmw_node_t * create_node(const char * implementation_identifier, const char * name, size_t domain_id) { DDSDomainParticipantFactory * dpf_ = DDSDomainParticipantFactory::get_instance(); if (!dpf_) { RMW_SET_ERROR_MSG("failed to get participant factory"); return NULL; } // use loopback interface to enable cross vendor communication DDS_DomainParticipantQos participant_qos; DDS_ReturnCode_t status = dpf_->get_default_participant_qos(participant_qos); if (status != DDS_RETCODE_OK) { RMW_SET_ERROR_MSG("failed to get default participant qos"); return NULL; } // forces local traffic to be sent over loopback, // even if a more efficient transport (such as shared memory) is installed // (in which case traffic will be sent over both transports) status = DDSPropertyQosPolicyHelper::add_property( participant_qos.property, "dds.transport.UDPv4.builtin.ignore_loopback_interface", "0", DDS_BOOLEAN_FALSE); if (status != DDS_RETCODE_OK) { RMW_SET_ERROR_MSG("failed to add qos property"); return NULL; } status = DDSPropertyQosPolicyHelper::add_property( participant_qos.property, "dds.transport.use_510_compatible_locator_kinds", "1", DDS_BOOLEAN_FALSE); if (status != DDS_RETCODE_OK) { RMW_SET_ERROR_MSG("failed to add qos property"); return NULL; } DDS_DomainId_t domain = static_cast<DDS_DomainId_t>(domain_id); DDSDomainParticipant * participant = dpf_->create_participant( domain, participant_qos, NULL, DDS_STATUS_MASK_NONE); if (!participant) { RMW_SET_ERROR_MSG("failed to create participant"); return NULL; } rmw_node_t * node_handle = nullptr; ConnextNodeInfo * node_info = nullptr; rmw_guard_condition_t * graph_guard_condition = nullptr; CustomPublisherListener * publisher_listener = nullptr; CustomSubscriberListener * subscriber_listener = nullptr; void * buf = nullptr; DDSDataReader * data_reader = nullptr; DDSPublicationBuiltinTopicDataDataReader * builtin_publication_datareader = nullptr; DDSSubscriptionBuiltinTopicDataDataReader * builtin_subscription_datareader = nullptr; DDSSubscriber * builtin_subscriber = participant->get_builtin_subscriber(); if (!builtin_subscriber) { RMW_SET_ERROR_MSG("builtin subscriber handle is null"); goto fail; } // setup publisher listener data_reader = builtin_subscriber->lookup_datareader(DDS_PUBLICATION_TOPIC_NAME); builtin_publication_datareader = static_cast<DDSPublicationBuiltinTopicDataDataReader *>(data_reader); if (!builtin_publication_datareader) { RMW_SET_ERROR_MSG("builtin publication datareader handle is null"); goto fail; } graph_guard_condition = create_guard_condition(implementation_identifier); if (!graph_guard_condition) { RMW_SET_ERROR_MSG("failed to create graph guard condition"); goto fail; } buf = rmw_allocate(sizeof(CustomPublisherListener)); if (!buf) { RMW_SET_ERROR_MSG("failed to allocate memory"); goto fail; } RMW_TRY_PLACEMENT_NEW( publisher_listener, buf, goto fail, CustomPublisherListener, implementation_identifier, graph_guard_condition) buf = nullptr; builtin_publication_datareader->set_listener(publisher_listener, DDS_DATA_AVAILABLE_STATUS); data_reader = builtin_subscriber->lookup_datareader(DDS_SUBSCRIPTION_TOPIC_NAME); builtin_subscription_datareader = static_cast<DDSSubscriptionBuiltinTopicDataDataReader *>(data_reader); if (!builtin_subscription_datareader) { RMW_SET_ERROR_MSG("builtin subscription datareader handle is null"); goto fail; } // setup subscriber listener buf = rmw_allocate(sizeof(CustomSubscriberListener)); if (!buf) { RMW_SET_ERROR_MSG("failed to allocate memory"); goto fail; } RMW_TRY_PLACEMENT_NEW( subscriber_listener, buf, goto fail, CustomSubscriberListener, implementation_identifier, graph_guard_condition) buf = nullptr; builtin_subscription_datareader->set_listener(subscriber_listener, DDS_DATA_AVAILABLE_STATUS); node_handle = rmw_node_allocate(); if (!node_handle) { RMW_SET_ERROR_MSG("failed to allocate memory for node handle"); goto fail; } node_handle->implementation_identifier = implementation_identifier; node_handle->data = participant; node_handle->name = reinterpret_cast<const char *>(rmw_allocate(sizeof(char) * strlen(name) + 1)); if (!node_handle->name) { RMW_SET_ERROR_MSG("failed to allocate memory for node name"); goto fail; } memcpy(const_cast<char *>(node_handle->name), name, strlen(name) + 1); buf = rmw_allocate(sizeof(ConnextNodeInfo)); if (!buf) { RMW_SET_ERROR_MSG("failed to allocate memory"); goto fail; } RMW_TRY_PLACEMENT_NEW(node_info, buf, goto fail, ConnextNodeInfo) buf = nullptr; node_info->participant = participant; node_info->publisher_listener = publisher_listener; node_info->subscriber_listener = subscriber_listener; node_info->graph_guard_condition = graph_guard_condition; node_handle->implementation_identifier = implementation_identifier; node_handle->data = node_info; return node_handle; fail: status = dpf_->delete_participant(participant); if (status != DDS_RETCODE_OK) { std::stringstream ss; ss << "leaking participant while handling failure at " << __FILE__ << ":" << __LINE__; (std::cerr << ss.str()).flush(); } if (graph_guard_condition) { rmw_ret_t ret = destroy_guard_condition(implementation_identifier, graph_guard_condition); if (ret != RMW_RET_OK) { std::stringstream ss; ss << "failed to destroy guard condition while handling failure at " << __FILE__ << ":" << __LINE__; (std::cerr << ss.str()).flush(); } } if (publisher_listener) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( publisher_listener->~CustomPublisherListener(), CustomPublisherListener) rmw_free(publisher_listener); } if (subscriber_listener) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( subscriber_listener->~CustomSubscriberListener(), CustomSubscriberListener) rmw_free(subscriber_listener); } if (node_handle) { if (node_handle->name) { rmw_free(const_cast<char *>(node_handle->name)); } rmw_free(node_handle); } if (node_info) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( node_info->~ConnextNodeInfo(), ConnextNodeInfo) rmw_free(node_info); } if (buf) { rmw_free(buf); } return NULL; }
void rmw_service_free(rmw_service_t * service) { // Should have matching overide with rmw_service_allocate rmw_free(service); }
rmw_node_t * rmw_create_node(const char * name, size_t domain_id) { if (!name) { RMW_SET_ERROR_MSG("name is null"); return nullptr; } DDS::DomainParticipantFactory_var dp_factory = DDS::DomainParticipantFactory::get_instance(); if (!dp_factory) { RMW_SET_ERROR_MSG("failed to get domain participant factory"); return nullptr; } DDS::DomainId_t domain = static_cast<DDS::DomainId_t>(domain_id); DDS::DomainParticipant * participant = nullptr; // Make sure that the OSPL_URI is set, otherwise node creation will fail. char * ospl_uri = nullptr; const char * ospl_uri_env = "OSPL_URI"; #ifndef _WIN32 ospl_uri = getenv(ospl_uri_env); #else size_t ospl_uri_size; _dupenv_s(&ospl_uri, &ospl_uri_size, ospl_uri_env); #endif if (!ospl_uri) { RMW_SET_ERROR_MSG("OSPL_URI not set"); return nullptr; } else { #ifdef _WIN32 free(ospl_uri); #endif } // Ensure the ROS_DOMAIN_ID env variable is set, otherwise parsing of the config may fail. // Also make sure the it is set to the domain_id passed in, otherwise it will fail. // But first backup the current ROS_DOMAIN_ID. char * ros_domain_id = nullptr; const char * env_var = "ROS_DOMAIN_ID"; #ifndef _WIN32 ros_domain_id = getenv(env_var); #else size_t ros_domain_id_size; _dupenv_s(&ros_domain_id, &ros_domain_id_size, env_var); #endif // On Windows, setting the ROS_DOMAIN_ID does not fix the problem, so error early. #ifdef _WIN32 if (!ros_domain_id) { RMW_SET_ERROR_MSG("environment variable ROS_DOMAIN_ID is not set"); fprintf(stderr, "[rmw_opensplice_cpp]: error: %s\n", rmw_get_error_string_safe()); return nullptr; } #endif // Set the ROS_DOMAIN_ID explicitly (if not Windows). #ifndef _WIN32 auto domain_id_as_string = std::to_string(domain_id); int ret = 0; ret = setenv(env_var, domain_id_as_string.c_str(), 1); if (0 != ret) { RMW_SET_ERROR_MSG("failed to set the ROS_DOMAIN_ID"); return nullptr; } #endif participant = dp_factory->create_participant( domain, PARTICIPANT_QOS_DEFAULT, NULL, DDS::STATUS_MASK_NONE); if (!participant) { RMW_SET_ERROR_MSG("failed to create domain participant"); return NULL; } // Restore the ROS_DOMAIN_ID if necessary (and not Windows). #ifndef _WIN32 if (ros_domain_id) { ret = setenv(env_var, ros_domain_id, 1); if (0 != ret) { RMW_SET_ERROR_MSG("failed to reset the ROS_DOMAIN_ID"); return nullptr; } } else { // Otherwise unset it again. ret = unsetenv(env_var); if (0 != ret) { RMW_SET_ERROR_MSG("failed to unset the ROS_DOMAIN_ID"); return nullptr; } } #endif rmw_node_t * node = nullptr; OpenSpliceStaticNodeInfo * node_info = nullptr; CustomPublisherListener * publisher_listener = nullptr; CustomSubscriberListener * subscriber_listener = nullptr; void * buf = nullptr; DDS::DataReader * data_reader = nullptr; DDS::PublicationBuiltinTopicDataDataReader * builtin_publication_datareader = nullptr; DDS::SubscriptionBuiltinTopicDataDataReader * builtin_subscription_datareader = nullptr; DDS::Subscriber * builtin_subscriber = participant->get_builtin_subscriber(); if (!builtin_subscriber) { RMW_SET_ERROR_MSG("builtin subscriber handle is null"); goto fail; } // setup publisher listener data_reader = builtin_subscriber->lookup_datareader("DCPSPublication"); builtin_publication_datareader = DDS::PublicationBuiltinTopicDataDataReader::_narrow(data_reader); if (!builtin_publication_datareader) { RMW_SET_ERROR_MSG("builtin publication datareader handle is null"); goto fail; } buf = rmw_allocate(sizeof(CustomPublisherListener)); if (!buf) { RMW_SET_ERROR_MSG("failed to allocate memory"); goto fail; } RMW_TRY_PLACEMENT_NEW(publisher_listener, buf, goto fail, CustomPublisherListener) buf = nullptr; builtin_publication_datareader->set_listener(publisher_listener, DDS::DATA_AVAILABLE_STATUS); data_reader = builtin_subscriber->lookup_datareader("DCPSSubscription"); builtin_subscription_datareader = DDS::SubscriptionBuiltinTopicDataDataReader::_narrow(data_reader); if (!builtin_subscription_datareader) { RMW_SET_ERROR_MSG("builtin subscription datareader handle is null"); goto fail; } // setup subscriber listener buf = rmw_allocate(sizeof(CustomSubscriberListener)); if (!buf) { RMW_SET_ERROR_MSG("failed to allocate memory"); goto fail; } RMW_TRY_PLACEMENT_NEW(subscriber_listener, buf, goto fail, CustomSubscriberListener) buf = nullptr; builtin_subscription_datareader->set_listener(subscriber_listener, DDS::DATA_AVAILABLE_STATUS); node = rmw_node_allocate(); if (!node) { RMW_SET_ERROR_MSG("failed to allocate rmw_node_t"); goto fail; } node->name = reinterpret_cast<const char *>(rmw_allocate(sizeof(char) * strlen(name) + 1)); if (!node->name) { RMW_SET_ERROR_MSG("failed to allocate memory for node name"); goto fail; } memcpy(const_cast<char *>(node->name), name, strlen(name) + 1); buf = rmw_allocate(sizeof(OpenSpliceStaticNodeInfo)); if (!buf) { RMW_SET_ERROR_MSG("failed to allocate memory"); goto fail; } RMW_TRY_PLACEMENT_NEW(node_info, buf, goto fail, OpenSpliceStaticNodeInfo) buf = nullptr; node_info->participant = participant; node_info->publisher_listener = publisher_listener; node_info->subscriber_listener = subscriber_listener; node->implementation_identifier = opensplice_cpp_identifier; node->data = node_info; return node; fail: if (participant) { if (dp_factory->delete_participant(participant) != DDS::RETCODE_OK) { std::stringstream ss; ss << "leaking domain participant while handling failure at: " << __FILE__ << ":" << __LINE__ << '\n'; (std::cerr << ss.str()).flush(); } } if (publisher_listener) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( publisher_listener->~CustomPublisherListener(), CustomPublisherListener) rmw_free(publisher_listener); } if (subscriber_listener) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( subscriber_listener->~CustomSubscriberListener(), CustomSubscriberListener) rmw_free(subscriber_listener); } if (node_info) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( node_info->~OpenSpliceStaticNodeInfo(), OpenSpliceStaticNodeInfo) rmw_free(node_info); } if (buf) { rmw_free(buf); } if (node) { if (node->name) { rmw_free(const_cast<char *>(node->name)); } rmw_node_free(node); } return nullptr; }
void rmw_guard_condition_free(rmw_guard_condition_t * guard_condition) { // Should have matching overide with rmw_guard_condition_allocate rmw_free(guard_condition); }
void rmw_subscription_free(rmw_subscription_t * subscription) { // Should have matching overide with rmw_subscription_allocate rmw_free(subscription); }
void rmw_publisher_free(rmw_publisher_t * publisher) { // Should have matching overide with rmw_publisher_allocate rmw_free(publisher); }
void rmw_node_free(rmw_node_t * node) { // Should have matching overide with rmw_node_allocate rmw_free(node); }
void rmw_waitset_free(rmw_waitset_t * waitset) { // Should have matching overide with rmw_waitset_allocate rmw_free(waitset); }
rmw_client_t * rmw_create_client( const rmw_node_t * node, const rosidl_service_type_support_t * type_support, const char * service_name, const rmw_qos_profile_t * qos_profile) { if (!node) { RMW_SET_ERROR_MSG("node handle is null"); return nullptr; } RMW_CHECK_TYPE_IDENTIFIERS_MATCH( node handle, node->implementation_identifier, opensplice_cpp_identifier, return nullptr) if (!type_support) { RMW_SET_ERROR_MSG("type support handle is null"); return nullptr; } RMW_CHECK_TYPE_IDENTIFIERS_MATCH( type support, type_support->typesupport_identifier, rosidl_typesupport_opensplice_cpp::typesupport_opensplice_identifier, return nullptr) if (!qos_profile) { RMW_SET_ERROR_MSG("qos_profile is null"); return nullptr; } auto node_info = static_cast<OpenSpliceStaticNodeInfo *>(node->data); if (!node_info) { RMW_SET_ERROR_MSG("node info handle is null"); return NULL; } auto participant = static_cast<DDS::DomainParticipant *>(node_info->participant); if (!participant) { RMW_SET_ERROR_MSG("participant handle is null"); return NULL; } const service_type_support_callbacks_t * callbacks = static_cast<const service_type_support_callbacks_t *>(type_support->data); if (!callbacks) { RMW_SET_ERROR_MSG("callbacks handle is null"); return NULL; } DDS::DataReaderQos datareader_qos; DDS::DataWriterQos datawriter_qos; // Past this point, a failure results in unrolling code in the goto fail block. rmw_client_t * client = nullptr; const char * error_string = nullptr; DDS::DataReader * response_datareader = nullptr; DDS::ReadCondition * read_condition = nullptr; void * requester = nullptr; OpenSpliceStaticClientInfo * client_info = nullptr; // Begin initializing elements. client = rmw_client_allocate(); if (!client) { RMW_SET_ERROR_MSG("failed to allocate client"); goto fail; } if (!get_datareader_qos(nullptr, *qos_profile, datareader_qos)) { goto fail; } if (!get_datawriter_qos(nullptr, *qos_profile, datawriter_qos)) { goto fail; } error_string = callbacks->create_requester( participant, service_name, reinterpret_cast<void **>(&requester), reinterpret_cast<void **>(&response_datareader), reinterpret_cast<const void *>(&datareader_qos), reinterpret_cast<const void *>(&datawriter_qos), &rmw_allocate); if (error_string) { RMW_SET_ERROR_MSG((std::string("failed to create requester: ") + error_string).c_str()); goto fail; } if (!requester) { RMW_SET_ERROR_MSG("failed to create requester: requester is null"); goto fail; } if (!response_datareader) { RMW_SET_ERROR_MSG("failed to create requester: response_datareader is null"); goto fail; } read_condition = response_datareader->create_readcondition( DDS::ANY_SAMPLE_STATE, DDS::ANY_VIEW_STATE, DDS::ANY_INSTANCE_STATE); if (!read_condition) { RMW_SET_ERROR_MSG("failed to create read condition"); goto fail; } client_info = static_cast<OpenSpliceStaticClientInfo *>( rmw_allocate(sizeof(OpenSpliceStaticClientInfo))); if (!client_info) { RMW_SET_ERROR_MSG("failed to allocate memory"); goto fail; } client_info->requester_ = requester; client_info->callbacks_ = callbacks; client_info->response_datareader_ = response_datareader; client_info->read_condition_ = read_condition; client->implementation_identifier = opensplice_cpp_identifier; client->data = client_info; client->service_name = reinterpret_cast<const char *>(rmw_allocate(strlen(service_name) + 1)); if (!client->service_name) { RMW_SET_ERROR_MSG("failed to allocate memory for node name"); goto fail; } memcpy(const_cast<char *>(client->service_name), service_name, strlen(service_name) + 1); return client; fail: if (response_datareader) { if (read_condition) { if (response_datareader->delete_readcondition(read_condition) != DDS::RETCODE_OK) { fprintf(stderr, "leaking readcondition while handling failure\n"); } } } if (requester) { const char * error_string = callbacks->destroy_requester(requester, &rmw_free); if (error_string) { std::stringstream ss; ss << "failed to destroy requester: " << error_string << ", at: " << __FILE__ << ":" << __LINE__ << '\n'; (std::cerr << ss.str()).flush(); } } if (client_info) { rmw_free(client_info); } if (client) { rmw_client_free(client); } return nullptr; }
rmw_ret_t rmw_destroy_node(rmw_node_t * node) { if (!node) { RMW_SET_ERROR_MSG("received null pointer"); return RMW_RET_ERROR; } RMW_CHECK_TYPE_IDENTIFIERS_MATCH( node handle, node->implementation_identifier, opensplice_cpp_identifier, return RMW_RET_ERROR) DDS::DomainParticipantFactory_var dp_factory = DDS::DomainParticipantFactory::get_instance(); if (!dp_factory) { RMW_SET_ERROR_MSG("failed to get domain participant factory"); return RMW_RET_ERROR; } auto node_info = static_cast<OpenSpliceStaticNodeInfo *>(node->data); if (!node_info) { RMW_SET_ERROR_MSG("node info handle is null"); return RMW_RET_ERROR; } auto participant = static_cast<DDS::DomainParticipant *>(node_info->participant); if (!participant) { RMW_SET_ERROR_MSG("participant handle is null"); return RMW_RET_ERROR; } auto result = RMW_RET_OK; // This unregisters types and destroys topics which were shared between // publishers and subscribers and could not be cleaned up in the delete functions. if (participant->delete_contained_entities() != DDS::RETCODE_OK) { RMW_SET_ERROR_MSG("failed to delete contained entities of participant"); result = RMW_RET_ERROR; } if (dp_factory->delete_participant(participant) != DDS::RETCODE_OK) { RMW_SET_ERROR_MSG("failed to delete participant"); result = RMW_RET_ERROR; } if (node_info->publisher_listener) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( node_info->publisher_listener->~CustomPublisherListener(), CustomPublisherListener) rmw_free(node_info->publisher_listener); node_info->publisher_listener = nullptr; } if (node_info->subscriber_listener) { RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE( node_info->subscriber_listener->~CustomSubscriberListener(), CustomSubscriberListener) rmw_free(node_info->subscriber_listener); node_info->subscriber_listener = nullptr; } rmw_free(node_info); node->data = nullptr; rmw_free(const_cast<char *>(node->name)); node->name = nullptr; rmw_node_free(node); return result; }
void rmw_client_free(rmw_client_t * client) { // Should have matching overide with rmw_client_allocate rmw_free(client); }