diff --git a/rcl/.gitignore b/rcl/.gitignore
new file mode 100644
index 0000000..94897f6
--- /dev/null
+++ b/rcl/.gitignore
@@ -0,0 +1 @@
+doc_output
diff --git a/rcl/Doxyfile b/rcl/Doxyfile
new file mode 100644
index 0000000..a0e5efe
--- /dev/null
+++ b/rcl/Doxyfile
@@ -0,0 +1,27 @@
+# All settings not listed here will use the Doxygen default values.
+
+PROJECT_NAME = "rcl"
+PROJECT_NUMBER = master
+PROJECT_BRIEF = "C API providing common ROS client library functionality."
+
+INPUT = ./include
+RECURSIVE = YES
+OUTPUT_DIRECTORY = doc_output
+
+EXTRACT_ALL = YES
+SORT_MEMBER_DOCS = NO
+
+GENERATE_LATEX = NO
+
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+PREDEFINED += RCL_PUBLIC=
+PREDEFINED += RCL_WARN_UNUSED=
+
+# Tag files that do not exist will produce a warning and cross-project linking will not work.
+TAGFILES += "../../../../doxygen_tag_files/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/"
+# Consider changing "latest" to the version you want to reference (e.g. beta1 or 1.0.0)
+TAGFILES += "../../../../doxygen_tag_files/rmw.tag=http://docs.ros2.org/latest/api/rmw/"
+# Uncomment to generate tag files for cross-project linking.
+#GENERATE_TAGFILE = "../../../../doxygen_tag_files/rcl.tag"
diff --git a/rcl/include/rcl/allocator.h b/rcl/include/rcl/allocator.h
index e1807d6..6ace7d8 100644
--- a/rcl/include/rcl/allocator.h
+++ b/rcl/include/rcl/allocator.h
@@ -25,7 +25,9 @@ extern "C"
#include "rcl/visibility_control.h"
/// Encapsulation of an allocator.
-/* To use malloc, free, and realloc use rcl_get_default_allocator().
+/**
+ * The default allocator uses std::malloc(), std::free(), and std::realloc().
+ * It can be obtained using rcl_get_default_allocator().
*
* The allocator should be trivially copyable.
* Meaning that the struct should continue to work after being assignment
@@ -37,37 +39,54 @@ extern "C"
*/
typedef struct rcl_allocator_t
{
- /// Allocate memory, given a size and state structure.
- /* An error should be indicated by returning NULL. */
+ /// Allocate memory, given a size and the `state` pointer.
+ /** An error should be indicated by returning `NULL`. */
void * (*allocate)(size_t size, void * state);
- /// Deallocate previously allocated memory, mimicking free().
+ /// Deallocate previously allocated memory, mimicking std::free().
+ /** Also takes the `state` pointer. */
void (* deallocate)(void * pointer, void * state);
/// Reallocate if possible, otherwise it deallocates and allocates.
- /* If unsupported then do deallocate and then allocate.
- * This should behave as realloc is described, as opposed to reallocf, i.e.
- * the memory given by pointer will not be free'd automatically if realloc
- * fails.
- * For reallocf behavior use rcl_reallocf().
- * This function must be able to take an input pointer of NULL and succeed.
+ /**
+ * Also takes the `state` pointer.
+ *
+ * If unsupported then do deallocate and then allocate.
+ * This should behave as std::realloc() does, as opposed to posix's
+ * [reallocf](https://linux.die.net/man/3/reallocf), i.e. the memory given
+ * by pointer will not be free'd automatically if std::realloc() fails.
+ * For reallocf-like behavior use rcl_reallocf().
+ * This function must be able to take an input pointer of `NULL` and succeed.
*/
void * (*reallocate)(void * pointer, size_t size, void * state);
/// Implementation defined state storage.
- /* This is passed as the second parameter to other allocator functions. */
+ /** This is passed as the final parameter to other allocator functions. */
void * state;
} rcl_allocator_t;
/// Return a properly initialized rcl_allocator_t with default values.
-/* This function does not allocate heap memory.
- * This function is thread-safe.
- * This function is lock-free.
+/**
+ * This defaults to:
+ *
+ * - allocate = wraps std::malloc()
+ * - deallocate = wraps std::free()
+ * - reallocate = wrapps std::realloc()
+ * - state = `NULL`
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | No
+ * Lock-Free | Yes
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_allocator_t
rcl_get_default_allocator(void);
-/// Emulate the behavior of reallocf.
-/* This function will return NULL if the allocator is NULL or has NULL for
+/// Emulate the behavior of [reallocf](https://linux.die.net/man/3/reallocf).
+/**
+ * This function will return `NULL` if the allocator is `NULL` or has `NULL` for
* function pointer fields.
*/
RCL_PUBLIC
diff --git a/rcl/include/rcl/client.h b/rcl/include/rcl/client.h
index a8694e6..a0d1de1 100644
--- a/rcl/include/rcl/client.h
+++ b/rcl/include/rcl/client.h
@@ -29,27 +29,26 @@ extern "C"
/// Internal rcl client implementation struct.
struct rcl_client_impl_t;
-/// Handle for a rcl client.
+/// Structure which encapsulates a ROS Client.
typedef struct rcl_client_t
{
struct rcl_client_impl_t * impl;
} rcl_client_t;
-/// Options available for a rcl client.
+/// Options available for a rcl_client_t.
typedef struct rcl_client_options_t
{
/// Middleware quality of service settings for the client.
rmw_qos_profile_t qos;
/// Custom allocator for the client, used for incidental allocations.
- /* For default behavior (malloc/free), use: rcl_get_default_allocator() */
+ /** For default behavior (malloc/free), use: rcl_get_default_allocator() */
rcl_allocator_t allocator;
} rcl_client_options_t;
-/// Return a rcl_client_t struct with members set to NULL.
-/* Should be called to get a null rcl_client_t before passing to
- * rcl_initalize_client().
- * It's also possible to use calloc() instead of this if the rcl_client is
- * being allocated on the heap.
+/// Return a rcl_client_t struct with members set to `NULL`.
+/**
+ * Should be called to get a null rcl_client_t before passing to
+ * rcl_client_init().
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -58,40 +57,47 @@ rcl_get_zero_initialized_client(void);
/// Initialize a rcl client.
-/* After calling this function on a rcl_client_t, it can be used to send requests of the given
- * type by calling rcl_send_request().
- * If the request is received by a (possibly remote) service and if the service sends a response,
- * the client can access the response through rcl_take_response once the response is available to
- * the client.
+/**
+ * After calling this function on a rcl_client_t, it can be used to send
+ * requests of the given type by calling rcl_send_request().
+ * If the request is received by a (possibly remote) service and if the service
+ * sends a response, the client can access the response through
+ * rcl_take_response() once the response is available to the client.
*
* The given rcl_node_t must be valid and the resulting rcl_client_t is only
* valid as long as the given rcl_node_t remains valid.
*
- * The rosidl_service_type_support_t is obtained on a per .srv type basis.
+ * The rosidl_service_type_support_t is obtained on a per `.srv` type basis.
* When the user defines a ROS service, code is generated which provides the
* required rosidl_service_type_support_t object.
* This object can be obtained using a language appropriate mechanism.
- * \TODO(wjwwood) probably should talk about this once and link to it instead
- * For C this macro can be used (using example_interfaces/AddTwoInts as an example):
+ * \todo TODO(wjwwood) write these instructions once and link to it instead
+ * For C a macro can be used (for example `example_interfaces/AddTwoInts`):
*
- * #include
- * #include
- * rosidl_service_type_support_t * ts =
- * ROSIDL_GET_SERVICE_TYPE_SUPPORT(example_interfaces, AddTwoInts);
+ * ```c
+ * #include
+ * #include
+ *
+ * rosidl_service_type_support_t * ts =
+ * ROSIDL_GET_SERVICE_TYPE_SUPPORT(example_interfaces, AddTwoInts);
+ * ```
*
* For C++ a template function is used:
*
- * #include
- * #include
- * rosidl_service_type_support_t * ts = rosidl_generator_cpp::get_service_type_support_handle<
- * example_interfaces::srv::AddTwoInts>();
+ * ```cpp
+ * #include
+ * #include
+ *
+ * rosidl_service_type_support_t * ts =
+ * rosidl_generator_cpp::get_service_type_support_handle();
+ * ```
*
* The rosidl_service_type_support_t object contains service type specific
* information used to send or take requests and responses.
*
- * \TODO(wjwwood) update this once we've come up with an official scheme.
- * The service name must be a non-empty string which follows the topic/service naming
- * format.
+ * \todo TODO(wjwwood) update this once we've come up with an official scheme.
+ * The service name must be a non-empty string which follows the topic/service
+ * name format conventions.
*
* The options struct allows the user to set the quality of service settings as
* well as a custom allocator which is used when initializing/finalizing the
@@ -99,38 +105,46 @@ rcl_get_zero_initialized_client(void);
*
* Expected usage (for C services):
*
- * #include
- * #include
- * #include
+ * ```cpp
+ * #include
+ * #include
+ * #include
*
- * rcl_node_t node = rcl_get_zero_initialized_node();
- * rcl_node_options_t node_ops = rcl_node_get_default_options();
- * rcl_ret_t ret = rcl_node_init(&node, "node_name", &node_ops);
- * // ... error handling
- * rosidl_service_type_support_t * ts = ROSIDL_GET_SERVICE_TYPE_SUPPORT(
- * example_interfaces, AddTwoInts);
- * rcl_client_t client = rcl_get_zero_initialized_client();
- * rcl_client_options_t client_ops = rcl_client_get_default_options();
- * ret = rcl_client_init(&client, &node, ts, "add_two_ints", &client_ops);
- * // ... error handling, and on shutdown do finalization:
- * ret = rcl_client_fini(&client, &node);
- * // ... error handling for rcl_client_fini()
- * ret = rcl_node_fini(&node);
- * // ... error handling for rcl_node_fini()
+ * rcl_node_t node = rcl_get_zero_initialized_node();
+ * rcl_node_options_t node_ops = rcl_node_get_default_options();
+ * rcl_ret_t ret = rcl_node_init(&node, "node_name", &node_ops);
+ * // ... error handling
+ * rosidl_service_type_support_t * ts = ROSIDL_GET_SERVICE_TYPE_SUPPORT(
+ * example_interfaces, AddTwoInts);
+ * rcl_client_t client = rcl_get_zero_initialized_client();
+ * rcl_client_options_t client_ops = rcl_client_get_default_options();
+ * ret = rcl_client_init(&client, &node, ts, "add_two_ints", &client_ops);
+ * // ... error handling, and on shutdown do finalization:
+ * ret = rcl_client_fini(&client, &node);
+ * // ... error handling for rcl_client_fini()
+ * ret = rcl_node_fini(&node);
+ * // ... error handling for rcl_node_fini()
+ * ```
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
- * \param[inout] client preallocated client structure
- * \param[in] node valid rcl node handle
+ * \param[inout] client preallocated rcl_client_t structure
+ * \param[in] node valid rcl_node_t
* \param[in] type_support type support object for the service's type
* \param[in] service_name the name of the service to request
* \param[in] options client options, including quality of service settings
- * \return RCL_RET_OK if the client was initialized successfully, or
- * RCL_RET_NODE_INVALID if the node is invalid, or
- * RCL_RET_ALREADY_INIT if the client is already initialized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory fails, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the client was initialized successfully, or
+ * \return `RCL_RET_NODE_INVALID` if the node is invalid, or
+ * \return `RCL_RET_ALREADY_INIT` if the client is already initialized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory fails, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -143,17 +157,24 @@ rcl_client_init(
const rcl_client_options_t * options);
/// Finalize a rcl_client_t.
-/*
- * After calling, calls to rcl_send_request and rcl_take_response will fail when using this client.
+/**
+ * After calling this function, calls to rcl_send_request() and
+ * rcl_take_response() will fail when using this client.
* However, the given node handle is still valid.
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] client handle to the client to be finalized
* \param[in] node handle to the node used to create the client
- * \return RCL_RET_OK if client was finalized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if client was finalized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -161,43 +182,60 @@ rcl_ret_t
rcl_client_fini(rcl_client_t * client, rcl_node_t * node);
/// Return the default client options in a rcl_client_options_t.
+/**
+ * The defaults are:
+ *
+ * - qos = rmw_qos_profile_services_default
+ * - allocator = rcl_get_default_allocator()
+ */
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_client_options_t
rcl_client_get_default_options(void);
/// Send a ROS request using a client.
-/* It is the job of the caller to ensure that the type of the ros_request
+/**
+ * It is the job of the caller to ensure that the type of the `ros_request`
* parameter and the type associate with the client (via the type support)
* match.
- * Passing a different type to send_request produces undefined behavior and cannot
- * be checked by this function and therefore no deliberate error will occur.
+ * Passing a different type to `send_request` produces undefined behavior and
+ * cannot be checked by this function and therefore no deliberate error will
+ * occur.
*
- * send_request is an non-blocking call.
+ * rcl_send_request() is an non-blocking call.
*
- * The ROS request message given by the ros_request void pointer is always owned by the
- * calling code, but should remain constant during send_request.
+ * The ROS request message given by the `ros_request` void pointer is always
+ * owned by the calling code, but should remain constant during `send_request`.
*
* This function is thread safe so long as access to both the client and the
- * ros_request is synchronized.
- * That means that calling rcl_send_request from multiple threads is allowed, but
- * calling rcl_send_request at the same time as non-thread safe client functions
- * is not, e.g. calling rcl_send_request and rcl_client_fini concurrently
- * is not allowed.
- * Before calling rcl_send_request the message can change and after calling
- * rcl_send_request the message can change, but it cannot be changed during the
- * send_request call.
- * The same ros_request, however, can be passed to multiple calls of
- * rcl_send_request simultaneously, even if the clients differ.
- * The ros_request is unmodified by rcl_send_request.
+ * `ros_request` is synchronized.
+ * That means that calling rcl_send_request() from multiple threads is allowed,
+ * but calling rcl_send_request() at the same time as non-thread safe client
+ * functions is not, e.g. calling rcl_send_request() and rcl_client_fini()
+ * concurrently is not allowed.
+ * Before calling rcl_send_request() the message can change and after calling
+ * rcl_send_request() the message can change, but it cannot be changed during
+ * the `send_request` call.
+ * The same `ros_request`, however, can be passed to multiple calls of
+ * rcl_send_request() simultaneously, even if the clients differ.
+ * The `ros_request` is unmodified by rcl_send_request().
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes [1]
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ * [1] for unique pairs of clients and requests, see above for more
*
* \param[in] client handle to the client which will make the response
* \param[in] ros_request type-erased pointer to the ROS request message
* \param[out] sequence_number the sequence number
- * \return RCL_RET_OK if the request was sent successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_CLIENT_INVALID if the client is invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the request was sent successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_CLIENT_INVALID` if the client is invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -205,24 +243,36 @@ rcl_ret_t
rcl_send_request(const rcl_client_t * client, const void * ros_request, int64_t * sequence_number);
-// Take a ROS response using a client
-/* It is the job of the caller to ensure that the type of the ros_response
+/// Take a ROS response using a client
+/**
+ * It is the job of the caller to ensure that the type of the `ros_response`
* parameter and the type associate with the client (via the type support)
* match.
- * Passing a different type to take_response produces undefined behavior and cannot
- * be checked by this function and therefore no deliberate error will occur.
- * The request_header is an rmw struct for meta-information about the request sent
- * (e.g. the sequence number).
- * ros_response should point to an already allocated ROS response message struct of the
- * correct type, into which the response from the service will be copied.
+ * Passing a different type to take_response produces undefined behavior and
+ * cannot be checked by this function and therefore no deliberate error will
+ * occur.
+ * The request_header is an rmw struct for meta-information about the request
+ * sent (e.g. the sequence number).
+ * `ros_response` should point to an already allocated ROS response message
+ * struct of the correct type, into which the response from the service will be
+ * copied.
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Maybe [1]
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ * [1] only if required when filling the message, avoided for fixed sizes
*
* \param[in] client handle to the client which will take the response
* \param[inout] request_header pointer to the request header
* \param[inout] ros_response type-erased pointer to the ROS response message
- * \return RCL_RET_OK if the response was taken successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_CLIENT_INVALID if the client is invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the response was taken successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_CLIENT_INVALID` if the client is invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -233,19 +283,26 @@ rcl_take_response(
void * ros_response);
/// Get the name of the service that this client will request a response from.
-/* This function returns the client's internal service name string.
- * This function can fail, and therefore return NULL, if the:
- * - client is NULL
+/**
+ * This function returns the client's internal service name string.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - client is `NULL`
* - client is invalid (never called init, called fini, or invalid node)
*
* The returned string is only valid as long as the rcl_client_t is valid.
* The value of the string may change if the service name changes, and therefore
* copying the string is recommended if this is a concern.
*
- * This function is not thread-safe, and copying the result is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] client pointer to the client
- * \return name string if successful, otherwise NULL
+ * \return name string if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -253,19 +310,26 @@ const char *
rcl_client_get_service_name(const rcl_client_t * client);
/// Return the rcl client options.
-/* This function returns the client's internal options struct.
- * This function can fail, and therefore return NULL, if the:
- * - client is NULL
+/**
+ * This function returns the client's internal options struct.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - client is `NULL`
* - client is invalid (never called init, called fini, or invalid node)
*
* The returned struct is only valid as long as the rcl_client_t is valid.
* The values in the struct may change if the options of the client change,
* and therefore copying the struct is recommended if this is a concern.
*
- * This function is not thread-safe, and copying the result is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] client pointer to the client
- * \return options struct if successful, otherwise NULL
+ * \return options struct if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -273,9 +337,10 @@ const rcl_client_options_t *
rcl_client_get_options(const rcl_client_t * client);
/// Return the rmw client handle.
-/* The handle returned is a pointer to the internally held rmw handle.
- * This function can fail, and therefore return NULL, if the:
- * - client is NULL
+/**
+ * The handle returned is a pointer to the internally held rmw handle.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - client is `NULL`
* - client is invalid (never called init, called fini, or invalid node)
*
* The returned handle is made invalid if the client is finalized or if
@@ -286,8 +351,16 @@ rcl_client_get_options(const rcl_client_t * client);
* this function each time it is needed and avoid use of the handle
* concurrently with functions that might change it.
*
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ *
* \param[in] client pointer to the rcl client
- * \return rmw client handle if successful, otherwise NULL
+ * \return rmw client handle if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/graph.h b/rcl/include/rcl/graph.h
index ad12326..25c6b66 100644
--- a/rcl/include/rcl/graph.h
+++ b/rcl/include/rcl/graph.h
@@ -33,16 +33,17 @@ extern "C"
typedef rmw_topic_names_and_types_t rcl_topic_names_and_types_t;
-/// Return a rcl_topic_names_and_types_t struct with members initialized to NULL.
+/// Return a rcl_topic_names_and_types_t struct with members initialized to `NULL`.
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_topic_names_and_types_t
rcl_get_zero_initialized_topic_names_and_types(void);
/// Return a list of topic names and their types.
-/* This function returns a list of topic names in the ROS graph and their types.
+/**
+ * This function returns a list of topic names in the ROS graph and their types.
*
- * The node parameter must not be NULL, and must point to a valid node.
+ * The node parameter must not be `NULL`, and must point to a valid node.
*
* The topic_names_and_types parameter must be allocated and zero initialized.
* The topic_names_and_types is the output for this function, and contains
@@ -51,16 +52,21 @@ rcl_get_zero_initialized_topic_names_and_types(void);
* it is no longer needed.
* Failing to do so will result in leaked memory.
*
- * This function does manipulate heap memory.
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Maybe [1]
+ * [1] implementation may need to protect the data structure with a lock
*
* \param[in] node the handle to the node being used to query the ROS graph
* \param[out] topic_names_and_types list of topic names and their types
- * \return RCL_RET_OK if the query was successful, or
- * RCL_RET_NODE_INVALID if the node is invalid, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the query was successful, or
+ * \return `RCL_RET_NODE_INVALID` if the node is invalid, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -70,18 +76,23 @@ rcl_get_topic_names_and_types(
rcl_topic_names_and_types_t * topic_names_and_types);
/// Destroy a struct which was previously given to rcl_get_topic_names_and_types.
-/* The topic_names_and_types parameter must not be NULL, and must point to an
+/**
+ * The topic_names_and_types parameter must not be `NULL`, and must point to an
* already allocated rcl_topic_names_and_types_t struct that was previously
* passed to a successful rcl_get_topic_names_and_types() call.
*
- * This function does manipulate heap memory.
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] topic_names_and_types struct to be destroyed
- * \return RCL_RET_OK if successful, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if successful, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -90,28 +101,34 @@ rcl_destroy_topic_names_and_types(
rcl_topic_names_and_types_t * topic_names_and_types);
/// Return the number of publishers on a given topic.
-/* This function returns the number of publishers on a given topic.
+/**
+ * This function returns the number of publishers on a given topic.
*
- * The node parameter must not be NULL, and must point to a valid node.
+ * The node parameter must not be `NULL`, and must point to a valid node.
*
- * The topic_name parameter must not be NULL, and must not be an empty string.
+ * The topic_name parameter must not be `NULL`, and must not be an empty string.
* It should also follow the topic name rules.
- * \TODO(wjwwood): link to the topic name rules.
+ * \todo TODO(wjwwood): link to the topic name rules.
*
- * The count parameter must not be NULL, and must point to a valid bool.
+ * The count parameter must not be `NULL`, and must point to a valid bool.
* The count parameter is the output for this function and will be set.
*
- * This function may manipulate heap memory.
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Maybe [1]
+ * [1] implementation may need to protect the data structure with a lock
*
* \param[in] node the handle to the node being used to query the ROS graph
* \param[in] topic_name the name of the topic in question
* \param[out] count number of publishers on the given topic
- * \return RCL_RET_OK if the query was successful, or
- * RCL_RET_NODE_INVALID if the node is invalid, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the query was successful, or
+ * \return `RCL_RET_NODE_INVALID` if the node is invalid, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -122,28 +139,34 @@ rcl_count_publishers(
size_t * count);
/// Return the number of subscriptions on a given topic.
-/* This function returns the number of subscriptions on a given topic.
+/**
+ * This function returns the number of subscriptions on a given topic.
*
- * The node parameter must not be NULL, and must point to a valid node.
+ * The node parameter must not be `NULL`, and must point to a valid node.
*
- * The topic_name parameter must not be NULL, and must not be an empty string.
+ * The topic_name parameter must not be `NULL`, and must not be an empty string.
* It should also follow the topic name rules.
- * \TODO(wjwwood): link to the topic name rules.
+ * \todo TODO(wjwwood): link to the topic name rules.
*
- * The count parameter must not be NULL, and must point to a valid bool.
+ * The count parameter must not be `NULL`, and must point to a valid bool.
* The count parameter is the output for this function and will be set.
*
- * This function may manipulate heap memory.
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Maybe [1]
+ * [1] implementation may need to protect the data structure with a lock
*
* \param[in] node the handle to the node being used to query the ROS graph
* \param[in] topic_name the name of the topic in question
* \param[out] count number of subscriptions on the given topic
- * \return RCL_RET_OK if the query was successful, or
- * RCL_RET_NODE_INVALID if the node is invalid, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the query was successful, or
+ * \return `RCL_RET_NODE_INVALID` if the node is invalid, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -154,30 +177,36 @@ rcl_count_subscribers(
size_t * count);
/// Check if a service server is available for the given service client.
-/* This function will return true for is_available if there is a service server
+/**
+ * This function will return true for is_available if there is a service server
* available for the given client.
*
- * The node parameter must not be NULL, and must point to a valid node.
+ * The node parameter must not be `NULL`, and must point to a valid node.
*
- * The client parameter must not be NULL, and must point to a valid client.
+ * The client parameter must not be `NULL`, and must point to a valid client.
*
* The given client and node must match, i.e. the client must have been created
* using the given node.
*
- * The is_available parameter must not be NULL, and must point a bool variable.
+ * The is_available parameter must not be `NULL`, and must point a bool variable.
* The result of the check will be stored in the is_available parameter.
*
- * This function does manipulate heap memory.
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Maybe [1]
+ * [1] implementation may need to protect the data structure with a lock
*
* \param[in] node the handle to the node being used to query the ROS graph
* \param[in] client the handle to the service client being queried
* \param[out] is_available set to true if there is a service server available, else false
- * \return RCL_RET_OK if the check was made successfully (regardless of the service readiness), or
- * RCL_RET_NODE_INVALID if the node is invalid, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the check was made successfully (regardless of the service readiness), or
+ * \return `RCL_RET_NODE_INVALID` if the node is invalid, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/guard_condition.h b/rcl/include/rcl/guard_condition.h
index 2d2738b..33f0f41 100644
--- a/rcl/include/rcl/guard_condition.h
+++ b/rcl/include/rcl/guard_condition.h
@@ -41,39 +41,47 @@ typedef struct rcl_guard_condition_options_t
rcl_allocator_t allocator;
} rcl_guard_condition_options_t;
-/// Return a rcl_guard_condition_t struct with members set to NULL.
+/// Return a rcl_guard_condition_t struct with members set to `NULL`.
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_guard_condition_t
rcl_get_zero_initialized_guard_condition(void);
/// Initialize a rcl guard_condition.
-/* After calling this function on a rcl_guard_condition_t, it can be passed to
+/**
+ * After calling this function on a rcl_guard_condition_t, it can be passed to
* rcl_wait() and then concurrently it can be triggered to wake-up rcl_wait().
*
* Expected usage:
*
- * #include
+ * ```c
+ * #include
*
- * // ... error handling
- * rcl_guard_condition_t guard_condition = rcl_get_zero_initialized_guard_condition();
- * ret = rcl_guard_condition_init(
- * &guard_condition, rcl_guard_condition_get_default_options());
- * // ... error handling, and on shutdown do deinitialization:
- * ret = rcl_guard_condition_fini(&guard_condition);
- * // ... error handling for rcl_guard_condition_fini()
+ * // ... error handling
+ * rcl_guard_condition_t guard_condition = rcl_get_zero_initialized_guard_condition();
+ * // ... customize guard condition options
+ * ret = rcl_guard_condition_init(
+ * &guard_condition, rcl_guard_condition_get_default_options());
+ * // ... error handling, and on shutdown do deinitialization:
+ * ret = rcl_guard_condition_fini(&guard_condition);
+ * // ... error handling for rcl_guard_condition_fini()
+ * ```
*
- * This function does allocate heap memory.
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] guard_condition preallocated guard_condition structure
* \param[in] options the guard_condition's options
- * \return RCL_RET_OK if guard_condition was initialized successfully, or
- * RCL_RET_ALREADY_INIT if the guard condition is already initialized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if guard_condition was initialized successfully, or
+ * \return `RCL_RET_ALREADY_INIT` if the guard condition is already initialized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -83,8 +91,9 @@ rcl_guard_condition_init(
const rcl_guard_condition_options_t options);
/// Same as rcl_guard_condition_init(), but reusing an existing rmw handle.
-/* In addition to the documentation for rcl_guard_condition_init(), the
- * rmw_guard_condition parameter must not be null and must point to a valid
+/**
+ * In addition to the documentation for rcl_guard_condition_init(), the
+ * `rmw_guard_condition` parameter must not be `NULL` and must point to a valid
* rmw guard condition.
*
* Also the life time of the rcl guard condition is tied to the life time of
@@ -95,14 +104,22 @@ rcl_guard_condition_init(
* Similarly if the resulting rcl guard condition is fini'ed before the rmw
* guard condition, then the rmw guard condition is no longer valid.
*
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ *
* \param[inout] guard_condition preallocated guard_condition structure
* \param[in] rmw_guard_condition existing rmw guard condition to reuse
* \param[in] options the guard_condition's options
- * \return RCL_RET_OK if guard_condition was initialized successfully, or
- * RCL_RET_ALREADY_INIT if the guard condition is already initialized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if guard_condition was initialized successfully, or
+ * \return `RCL_RET_ALREADY_INIT` if the guard condition is already initialized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
rcl_ret_t
rcl_guard_condition_init_from_rmw(
@@ -111,17 +128,23 @@ rcl_guard_condition_init_from_rmw(
const rcl_guard_condition_options_t options);
/// Finalize a rcl_guard_condition_t.
-/* After calling, calls to rcl_trigger_guard_condition() will fail when using
+/**
+ * After calling, calls to rcl_trigger_guard_condition() will fail when using
* this guard condition.
*
- * This function does free heap memory and can allocate memory on errors.
- * This function is not thread-safe with rcl_trigger_guard_condition().
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No [1]
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ * [1] specifically not thread-safe with rcl_trigger_guard_condition()
*
* \param[inout] guard_condition handle to the guard_condition to be finalized
- * \return RCL_RET_OK if guard_condition was finalized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if guard_condition was finalized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -129,9 +152,10 @@ rcl_ret_t
rcl_guard_condition_fini(rcl_guard_condition_t * guard_condition);
/// Return the default options in a rcl_guard_condition_options_t struct.
-/* This function does not allocate heap memory.
- * This function is thread-safe.
- * This function is lock-free.
+/**
+ * The defaults are:
+ *
+ * - allocator = rcl_get_default_allocator()
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -139,21 +163,26 @@ rcl_guard_condition_options_t
rcl_guard_condition_get_default_options(void);
/// Trigger a rcl guard condition.
-/* This function can fail, and return RCL_RET_INVALID_ARGUMENT, if the:
- * - guard condition is NULL
+/**
+ * This function can fail, and return RCL_RET_INVALID_ARGUMENT, if the:
+ * - guard condition is `NULL`
* - guard condition is invalid (never called init or called fini)
*
* A guard condition can be triggered from any thread.
*
- * This function does not allocate heap memory, but can on errors.
- * This function is thread-safe with itself, but cannot be called concurrently
- * with rcl_guard_condition_fini() on the same guard condition.
- * This function is lock-free, but the underlying system calls may not be.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No [1]
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ * [1] it can be called concurrently with itself, even on the same guard condition
*
* \param[in] guard_condition handle to the guard_condition to be triggered
- * \return RCL_RET_OK if the guard condition was triggered, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the guard condition was triggered, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -161,9 +190,10 @@ rcl_ret_t
rcl_trigger_guard_condition(rcl_guard_condition_t * guard_condition);
/// Return the rmw guard condition handle.
-/* The handle returned is a pointer to the internally held rmw handle.
- * This function can fail, and therefore return NULL, if the:
- * - guard_condition is NULL
+/**
+ * The handle returned is a pointer to the internally held rmw handle.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - guard_condition is `NULL`
* - guard_condition is invalid (never called init, called fini, or invalid node)
*
* The returned handle is made invalid if the guard condition is finalized or
@@ -174,8 +204,16 @@ rcl_trigger_guard_condition(rcl_guard_condition_t * guard_condition);
* this function each time it is needed and avoid use of the handle
* concurrently with functions that might change it.
*
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ *
* \param[in] guard_condition pointer to the rcl guard_condition
- * \return rmw guard_condition handle if successful, otherwise NULL
+ * \return rmw guard condition handle if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/macros.h b/rcl/include/rcl/macros.h
index 2399307..192110a 100644
--- a/rcl/include/rcl/macros.h
+++ b/rcl/include/rcl/macros.h
@@ -21,6 +21,7 @@ extern "C"
#endif
#ifndef _WIN32
+/// Ignored return values of functions with this macro will emit a warning.
# define RCL_WARN_UNUSED __attribute__((warn_unused_result))
#else
# define RCL_WARN_UNUSED _Check_return_
diff --git a/rcl/include/rcl/node.h b/rcl/include/rcl/node.h
index 0bcbaa1..2c8a0a4 100644
--- a/rcl/include/rcl/node.h
+++ b/rcl/include/rcl/node.h
@@ -27,18 +27,20 @@ extern "C"
#include "rcl/types.h"
#include "rcl/visibility_control.h"
+/// Constant which indicates that the default domain id should be used.
#define RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID SIZE_MAX
struct rcl_guard_condition_t;
struct rcl_node_impl_t;
-/// Handle for a ROS node.
+/// Structure which encapsulates a ROS Node.
typedef struct rcl_node_t
{
/// Private implementation pointer.
struct rcl_node_impl_t * impl;
} rcl_node_t;
+/// Structure which encapsulates the options for creating a rcl_node_t.
typedef struct rcl_node_options_t
{
// bool anonymous_name;
@@ -46,35 +48,46 @@ typedef struct rcl_node_options_t
/// If true, no parameter infrastructure will be setup.
// bool no_parameters;
/// If set, then this value overrides the ROS_DOMAIN_ID environment variable.
- /* It defaults to RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID, which will cause the
+ /**
+ * It defaults to RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID, which will cause the
* node to use the ROS domain ID set in the ROS_DOMAIN_ID environment
* variable, or on some systems 0 if the environment variable is not set.
*
- * \TODO(wjwwood): Should we put a limit on the ROS_DOMAIN_ID value, that way
- * we can have a safe value for the default
- * RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID? (currently max size_t)
+ * \todo TODO(wjwwood):
+ * Should we put a limit on the ROS_DOMAIN_ID value, that way we can have
+ * a safe value for the default RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID?
+ * (currently max size_t)
*/
size_t domain_id;
/// Custom allocator used for internal allocations.
rcl_allocator_t allocator;
} rcl_node_options_t;
-/// Return a rcl_node_t struct with members initialized to NULL.
+/// Return a rcl_node_t struct with members initialized to `NULL`.
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_node_t
rcl_get_zero_initialized_node(void);
/// Initialize a ROS node.
-/* Calling this on a rcl_node_t makes it a valid node handle until rcl_shutdown
+/**
+ * Calling this on a rcl_node_t makes it a valid node handle until rcl_shutdown
* is called or until rcl_node_fini is called on it.
*
- * After calling the ROS node object can be used to create other middleware
- * primitives like publishers, services, parameters, and etc.
+ * After calling, the ROS node object can be used to create other middleware
+ * primitives like publishers, services, parameters, etc.
+ *
+ * \todo TODO(wjwwood): node name uniqueness is no yet enforced
*
* The name of the node cannot coincide with another node of the same name.
* If a node of the same name is already in the domain, it will be shutdown.
*
+ * \todo TODO(wjwwood):
+ * Parameter infrastructure is currently initialized in the language specific
+ * client library, e.g. rclcpp for C++, but will be initialized here in the
+ * future. When that happens there will be an option to avoid parameter
+ * infrastructure with an option in the rcl_node_options_t struct.
+ *
* A node contains infrastructure for ROS parameters, which include advertising
* publishers and service servers.
* This function will create those external parameter interfaces even if
@@ -87,29 +100,36 @@ rcl_get_zero_initialized_node(void);
*
* Expected usage:
*
- * rcl_node_t node = rcl_get_zero_initialized_node();
- * rcl_node_options_t * node_ops = rcl_node_get_default_options();
- * rcl_ret_t ret = rcl_node_init(&node, "node_name", node_ops);
- * // ... error handling and then use the node, but finally deinitialize it:
- * ret = rcl_node_fini(&node);
- * // ... error handling for rcl_node_fini()
+ * ```c
+ * rcl_node_t node = rcl_get_zero_initialized_node();
+ * rcl_node_options_t * node_ops = rcl_node_get_default_options();
+ * // ... node options customization
+ * rcl_ret_t ret = rcl_node_init(&node, "node_name", node_ops);
+ * // ... error handling and then use the node, but eventually deinitialize it:
+ * ret = rcl_node_fini(&node);
+ * // ... error handling for rcl_node_fini()
+ * ```
*
- * This function allocates heap memory.
- * This function is not thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_uint_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_uint_least64_t`
*
* \pre the node handle must be allocated, zero initialized, and invalid
- * \post the node handle is valid and can be used to in other rcl_* functions
+ * \post the node handle is valid and can be used in other `rcl_*` functions
*
- * \param[inout] node a preallocated node structure
+ * \param[inout] node a preallocated rcl_node_t
* \param[in] name the name of the node
- * \param[in] options the node options; pass null to use default options
- * \return RCL_RET_OK if node was initialized successfully, or
- * RCL_RET_ALREADY_INIT if the node has already be initialized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \param[in] options the node options
+ * \return `RCL_RET_OK` if the node was initialized successfully, or
+ * \return `RCL_RET_ALREADY_INIT` if the node has already be initialized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -117,21 +137,26 @@ rcl_ret_t
rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * options);
/// Finalized a rcl_node_t.
-/* Shuts down any automatically created infrastructure and deallocates memory.
+/**
+ * Destroys any automatically created infrastructure and deallocates memory.
* After calling, the rcl_node_t can be safely deallocated.
*
* Any middleware primitives created by the user, e.g. publishers, services, etc.,
* are invalid after deinitialization.
*
- * This function manipulates heap memory.
- * This function is not thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_uint_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_uint_least64_t`
*
- * \param[in] node handle to the node to be finalized
- * \return RCL_RET_OK if node was finalized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \param[in] node rcl_node_t to be finalized
+ * \return `RCL_RET_OK` if node was finalized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -139,57 +164,76 @@ rcl_ret_t
rcl_node_fini(rcl_node_t * node);
/// Return the default node options in a rcl_node_options_t.
+/**
+ * The default values are:
+ *
+ * - domain_id = RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID
+ * - allocator = rcl_get_default_allocator()
+ */
RCL_PUBLIC
rcl_node_options_t
rcl_node_get_default_options(void);
-/// Return true if the node is valid, else false.
-/* Also return false if the node pointer is nullptr.
+/// Return `true` if the node is valid, else `false`.
+/**
+ * Also return `false` if the node pointer is `NULL`.
*
* A node is invalid if:
- * - the implementation is null (rcl_node_init not called or failed)
+ * - the implementation is `NULL` (rcl_node_init not called or failed)
* - rcl_shutdown has been called since the node has been initialized
* - the node has been finalized with rcl_node_fini
*
* There is a possible validity race condition.
+ *
* Consider:
*
- * assert(rcl_node_is_valid(node)); <-- thread 1
- * rcl_shutdown(); <-- thread 2
- * // use node as if valid <-- thread 1
+ * ```c
+ * assert(rcl_node_is_valid(node)); // <-- thread 1
+ * rcl_shutdown(); // <-- thread 2
+ * // use node as if valid // <-- thread 1
+ * ```
*
* In the third line the node is now invalid, even though on the previous line
* of thread 1 it was checked to be valid.
* This is why this function is considered not thread-safe.
*
- * This function does not manipulate heap memory.
- * This function is not thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_uint_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_uint_least64_t`
*
- * \param[in] node handle to the node to validated
- * \return true if the node is valid, otherwise false.
+ * \param[in] node rcl_node_t to be validated
+ * \return `true` if the node is valid, otherwise `false`.
*/
RCL_PUBLIC
bool
rcl_node_is_valid(const rcl_node_t * node);
-/// Get the name of the node.
-/* This function returns the node's internal name string.
- * This function can fail, and therefore return NULL, if:
- * - node is NULL
+/// Return the name of the node.
+/**
+ * This function returns the node's internal name string.
+ * This function can fail, and therefore return `NULL`, if:
+ * - node is `NULL`
* - node has not been initialized (the implementation is invalid)
*
* The returned string is only valid as long as the given rcl_node_t is valid.
* The value of the string may change if the value in the rcl_node_t changes,
* and therefore copying the string is recommended if this is a concern.
*
- * This function does not manipulate heap memory.
- * This function is thread-safe for different nodes.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] node pointer to the node
- * \return name string if successful, otherwise NULL
+ * \return name string if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -197,21 +241,26 @@ const char *
rcl_node_get_name(const rcl_node_t * node);
/// Return the rcl node options.
-/* This function returns the node's internal options struct.
- * This function can fail, and therefore return NULL, if:
- * - node is NULL
+/**
+ * This function returns the node's internal options struct.
+ * This function can fail, and therefore return `NULL`, if:
+ * - node is `NULL`
* - node has not been initialized (the implementation is invalid)
*
* The returned struct is only valid as long as the given rcl_node_t is valid.
* The values in the struct may change if the options of the rcl_node_t changes,
* and therefore copying the struct is recommended if this is a concern.
*
- * This function does not manipulate heap memory.
- * This function is thread-safe for different nodes.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] node pointer to the node
- * \return options struct if successful, otherwise NULL
+ * \return options struct if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -219,26 +268,32 @@ const rcl_node_options_t *
rcl_node_get_options(const rcl_node_t * node);
/// Return the ROS domain ID that the node is using.
-/* This function returns the ROS domain ID that the node is in.
+/**
+ * This function returns the ROS domain ID that the node is in.
*
- * This function should be used to determine what domain_id was used rather
+ * This function should be used to determine what `domain_id` was used rather
* than checking the domin_id field in the node options, because if
- * RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID is used when creating the node then
+ * `RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID` is used when creating the node then
* it is not changed after creation, but this function will return the actual
- * domain_id used.
+ * `domain_id` used.
*
- * The domain_id field must point to an allocated size_t object to which the
- * ROS domain ID will be written.
+ * The `domain_id` field must point to an allocated `size_t` object to which
+ * the ROS domain ID will be written.
*
- * This function does not manipulate heap memory.
- * This function is thread-safe for different nodes.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] node the handle to the node being queried
- * \return RCL_RET_OK if node the domain ID was retrieved successfully, or
- * RCL_RET_NODE_INVALID if the node is invalid, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \param[out] domain_id storage for the domain id
+ * \return `RCL_RET_OK` if node the domain ID was retrieved successfully, or
+ * \return `RCL_RET_NODE_INVALID` if the node is invalid, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -246,9 +301,10 @@ rcl_ret_t
rcl_node_get_domain_id(const rcl_node_t * node, size_t * domain_id);
/// Return the rmw node handle.
-/* The handle returned is a pointer to the internally held rmw handle.
- * This function can fail, and therefore return NULL, if:
- * - node is NULL
+/**
+ * The handle returned is a pointer to the internally held rmw handle.
+ * This function can fail, and therefore return `NULL`, if:
+ * - node is `NULL`
* - node has not been initialized (the implementation is invalid)
*
* The returned handle is made invalid if the node is finalized or if
@@ -259,12 +315,16 @@ rcl_node_get_domain_id(const rcl_node_t * node, size_t * domain_id);
* this function each time it is needed and avoid use of the handle
* concurrently with functions that might change it.
*
- * This function does not manipulate heap memory.
- * This function is thread-safe for different nodes.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] node pointer to the rcl node
- * \return rmw node handle if successful, otherwise NULL
+ * \return rmw node handle if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -272,23 +332,28 @@ rmw_node_t *
rcl_node_get_rmw_handle(const rcl_node_t * node);
/// Return the associated rcl instance id.
-/* This id is stored when rcl_node_init is called and can be compared with the
+/**
+ * This id is stored when rcl_node_init is called and can be compared with the
* value returned by rcl_get_instance_id() to check if this node was created in
* the current rcl context (since the latest call to rcl_init().
*
- * This function can fail, and therefore return 0, if:
- * - node is NULL
+ * This function can fail, and therefore return `0`, if:
+ * - node is `NULL`
* - node has not been initialized (the implementation is invalid)
*
- * This function will succeed, however, even if rcl_shutdown has been called
+ * This function will succeed even if rcl_shutdown() has been called
* since the node was created.
*
- * This function does not manipulate heap memory.
- * This function is thread-safe for different nodes.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] node pointer to the rcl node
- * \return rcl instance id captured at node creation or 0 if there was an error
+ * \return rcl instance id captured during node init or `0` on error
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -296,9 +361,10 @@ uint64_t
rcl_node_get_rcl_instance_id(const rcl_node_t * node);
/// Return a guard condition which is triggered when the ROS graph changes.
-/* The handle returned is a pointer to an internally held rcl guard condition.
- * This function can fail, and therefore return NULL, if:
- * - node is NULL
+/**
+ * The handle returned is a pointer to an internally held rcl guard condition.
+ * This function can fail, and therefore return `NULL`, if:
+ * - node is `NULL`
* - node is invalid
*
* The returned handle is made invalid if the node is finialized or if
@@ -309,13 +375,18 @@ rcl_node_get_rcl_instance_id(const rcl_node_t * node);
* advertises, a new subscription is created, a new service becomes available,
* a subscription is canceled, etc.
*
- * This function does not manipulate heap memory.
- * This function is thread-safe.
- * This function is lock-free.
+ * \todo TODO(wjwwood): link to exhaustive list of graph events
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] node pointer to the rcl node
- * \return rcl guard condition handle if successful, otherwise NULL
- *
+ * \return rcl guard condition handle if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/publisher.h b/rcl/include/rcl/publisher.h
index 6057548..dd6f474 100644
--- a/rcl/include/rcl/publisher.h
+++ b/rcl/include/rcl/publisher.h
@@ -29,7 +29,7 @@ extern "C"
/// Internal rcl publisher implementation struct.
struct rcl_publisher_impl_t;
-/// Handle for a rcl publisher.
+/// Structure which encapsulates a ROS Publisher.
typedef struct rcl_publisher_t
{
struct rcl_publisher_impl_t * impl;
@@ -41,15 +41,14 @@ typedef struct rcl_publisher_options_t
/// Middleware quality of service settings for the publisher.
rmw_qos_profile_t qos;
/// Custom allocator for the publisher, used for incidental allocations.
- /* For default behavior (malloc/free), use: rcl_get_default_allocator() */
+ /** For default behavior (malloc/free), use: rcl_get_default_allocator() */
rcl_allocator_t allocator;
} rcl_publisher_options_t;
-/// Return a rcl_publisher_t struct with members set to NULL.
-/* Should be called to get a null rcl_publisher_t before passing to
- * rcl_initalize_publisher().
- * It's also possible to use calloc() instead of this if the rcl_publisher is
- * being allocated on the heap.
+/// Return a rcl_publisher_t struct with members set to `NULL`.
+/**
+ * Should be called to get a null rcl_publisher_t before passing to
+ * rcl_publisher_init().
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -57,7 +56,8 @@ rcl_publisher_t
rcl_get_zero_initialized_publisher(void);
/// Initialize a rcl publisher.
-/* After calling this function on a rcl_publisher_t, it can be used to publish
+/**
+ * After calling this function on a rcl_publisher_t, it can be used to publish
* messages of the given type to the given topic using rcl_publish().
*
* The given rcl_node_t must be valid and the resulting rcl_publisher_t is only
@@ -67,25 +67,29 @@ rcl_get_zero_initialized_publisher(void);
* When the user defines a ROS message, code is generated which provides the
* required rosidl_message_type_support_t object.
* This object can be obtained using a language appropriate mechanism.
- * \TODO(wjwwood) probably should talk about this once and link to it instead
- * For C this macro can be used (using std_msgs/String as an example):
+ * \todo TODO(wjwwood) write these instructions once and link to it instead
+ * For C a macro can be used (for example `std_msgs/String`):
*
- * #include
- * #include
- * rosidl_message_type_support_t * string_ts =
- * ROSIDL_GET_MESSAGE_TYPE_SUPPORT(std_msgs, String);
+ * ```c
+ * #include
+ * #include
+ * rosidl_message_type_support_t * string_ts =
+ * ROSIDL_GET_MESSAGE_TYPE_SUPPORT(std_msgs, String);
+ * ```
*
* For C++ a template function is used:
*
- * #include
- * #include
- * rosidl_message_type_support_t * string_ts =
- * rosidl_generator_cpp::get_message_type_support_handle();
+ * ```cpp
+ * #include
+ * #include
+ * rosidl_message_type_support_t * string_ts =
+ * rosidl_generator_cpp::get_message_type_support_handle();
+ * ```
*
* The rosidl_message_type_support_t object contains message type specific
* information used to publish messages.
*
- * \TODO(wjwwood) update this once we've come up with an official scheme.
+ * \todo TODO(wjwwood) update this once we've come up with an official scheme.
* The topic name must be a non-empty string which follows the topic naming
* format.
*
@@ -95,37 +99,45 @@ rcl_get_zero_initialized_publisher(void);
*
* Expected usage (for C messages):
*
- * #include
- * #include
- * #include
+ * ```c
+ * #include
+ * #include
+ * #include
*
- * rcl_node_t node = rcl_get_zero_initialized_node();
- * rcl_node_options_t node_ops = rcl_node_get_default_options();
- * rcl_ret_t ret = rcl_node_init(&node, "node_name", &node_ops);
- * // ... error handling
- * rosidl_message_type_support_t * ts = ROSIDL_GET_MESSAGE_TYPE_SUPPORT(std_msgs, String);
- * rcl_publisher_t publisher = rcl_get_zero_initialized_publisher();
- * rcl_publisher_options_t publisher_ops = rcl_publisher_get_default_options();
- * ret = rcl_publisher_init(&publisher, &node, ts, "chatter", &publisher_ops);
- * // ... error handling, and on shutdown do finalization:
- * ret = rcl_publisher_fini(&publisher, &node);
- * // ... error handling for rcl_publisher_fini()
- * ret = rcl_node_fini(&node);
- * // ... error handling for rcl_deinitialize_node()
+ * rcl_node_t node = rcl_get_zero_initialized_node();
+ * rcl_node_options_t node_ops = rcl_node_get_default_options();
+ * rcl_ret_t ret = rcl_node_init(&node, "node_name", &node_ops);
+ * // ... error handling
+ * rosidl_message_type_support_t * ts = ROSIDL_GET_MESSAGE_TYPE_SUPPORT(std_msgs, String);
+ * rcl_publisher_t publisher = rcl_get_zero_initialized_publisher();
+ * rcl_publisher_options_t publisher_ops = rcl_publisher_get_default_options();
+ * ret = rcl_publisher_init(&publisher, &node, ts, "chatter", &publisher_ops);
+ * // ... error handling, and on shutdown do finalization:
+ * ret = rcl_publisher_fini(&publisher, &node);
+ * // ... error handling for rcl_publisher_fini()
+ * ret = rcl_node_fini(&node);
+ * // ... error handling for rcl_deinitialize_node()
+ * ```
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] publisher preallocated publisher structure
* \param[in] node valid rcl node handle
* \param[in] type_support type support object for the topic's type
* \param[in] topic_name the name of the topic to publish on
* \param[in] options publisher options, including quality of service settings
- * \return RCL_RET_OK if the publisher was initialized successfully, or
- * RCL_RET_NODE_INVALID if the node is invalid, or
- * RCL_RET_ALREADY_INIT if the publisher is already initialized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory fails, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the publisher was initialized successfully, or
+ * \return `RCL_RET_NODE_INVALID` if the node is invalid, or
+ * \return `RCL_RET_ALREADY_INIT` if the publisher is already initialized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory fails, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -138,19 +150,26 @@ rcl_publisher_init(
const rcl_publisher_options_t * options);
/// Finalize a rcl_publisher_t.
-/* After calling, the node will no longer be advertising that it is publishing
+/**
+ * After calling, the node will no longer be advertising that it is publishing
* on this topic (assuming this is the only publisher on this topic).
*
* After calling, calls to rcl_publish will fail when using this publisher.
* However, the given node handle is still valid.
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] publisher handle to the publisher to be finalized
* \param[in] node handle to the node used to create the publisher
- * \return RCL_RET_OK if publisher was finalized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if publisher was finalized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -158,23 +177,32 @@ rcl_ret_t
rcl_publisher_fini(rcl_publisher_t * publisher, rcl_node_t * node);
/// Return the default publisher options in a rcl_publisher_options_t.
+/**
+ * The defaults are:
+ *
+ * - qos = rmw_qos_profile_default
+ * - allocator = rcl_get_default_allocator()
+ */
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_publisher_options_t
rcl_publisher_get_default_options(void);
/// Publish a ROS message on a topic using a publisher.
-/* It is the job of the caller to ensure that the type of the ros_message
+/**
+ * It is the job of the caller to ensure that the type of the ros_message
* parameter and the type associate with the publisher (via the type support)
* match.
* Passing a different type to publish produces undefined behavior and cannot
* be checked by this function and therefore no deliberate error will occur.
*
- * TODO(wjwwood): update after researching what the blocking behavior is
- * or optionally link to a document that describes blocking
- * behavior is more detail.
- * Calling rcl_publish is a potentially blocking call.
- * When called rcl_publish will immediately do any publishing related work,
+ * \todo TODO(wjwwood):
+ * The blocking behavior of publish is a still a point of dispute.
+ * This section should be updated once the behavior is clearly defined.
+ * See: https://github.com/ros2/ros2/issues/255
+ *
+ * Calling rcl_publish() is a potentially blocking call.
+ * When called rcl_publish() will immediately do any publishing related work,
* including, but not limited to, converting the message into a different type,
* serializing the message, collecting publish statistics, etc.
* The last thing it will do is call the underlying middleware's publish
@@ -184,28 +212,37 @@ rcl_publisher_get_default_options(void);
* until space in the publish queue is available, but if the reliability is set
* to best effort then it should not block.
*
- * The ROS message given by the ros_message void pointer is always owned by the
- * calling code, but should remain constant during publish.
+ * The ROS message given by the `ros_message` void pointer is always owned by
+ * the calling code, but should remain constant during publish.
*
* This function is thread safe so long as access to both the publisher and the
- * ros_message is synchronized.
- * That means that calling rcl_publish from multiple threads is allowed, but
- * calling rcl_publish at the same time as non-thread safe publisher functions
- * is not, e.g. calling rcl_publish and rcl_publisher_fini concurrently
- * is not allowed.
- * Before calling rcl_publish the message can change and after calling
- * rcl_publish the message can change, but it cannot be changed during the
+ * `ros_message` is synchronized.
+ * That means that calling rcl_publish() from multiple threads is allowed, but
+ * calling rcl_publish() at the same time as non-thread safe publisher
+ * functions is not, e.g. calling rcl_publish() and rcl_publisher_fini()
+ * concurrently is not allowed.
+ * Before calling rcl_publish() the message can change and after calling
+ * rcl_publish() the message can change, but it cannot be changed during the
* publish call.
- * The same ros_message, however, can be passed to multiple calls of
- * rcl_publish simultaneously, even if the publishers differ.
- * The ros_message is unmodified by rcl_publish.
+ * The same `ros_message`, however, can be passed to multiple calls of
+ * rcl_publish() simultaneously, even if the publishers differ.
+ * The `ros_message` is unmodified by rcl_publish().
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes [1]
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ * [1] for unique pairs of publishers and messages, see above for more
*
* \param[in] publisher handle to the publisher which will do the publishing
* \param[in] ros_message type-erased pointer to the ROS message
- * \return RCL_RET_OK if the message was published successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_PUBLISHER_INVALID if the publisher is invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the message was published successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_PUBLISHER_INVALID` if the publisher is invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -213,19 +250,26 @@ rcl_ret_t
rcl_publish(const rcl_publisher_t * publisher, const void * ros_message);
/// Get the topic name for the publisher.
-/* This function returns the publisher's internal topic name string.
- * This function can fail, and therefore return NULL, if the:
- * - publisher is NULL
+/**
+ * This function returns the publisher's internal topic name string.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - publisher is `NULL`
* - publisher is invalid (never called init, called fini, or invalid node)
*
* The returned string is only valid as long as the rcl_publisher_t is valid.
* The value of the string may change if the topic name changes, and therefore
* copying the string is recommended if this is a concern.
*
- * This function is not thread-safe, and copying the result is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] publisher pointer to the publisher
- * \return name string if successful, otherwise NULL
+ * \return name string if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -233,19 +277,26 @@ const char *
rcl_publisher_get_topic_name(const rcl_publisher_t * publisher);
/// Return the rcl publisher options.
-/* This function returns the publisher's internal options struct.
- * This function can fail, and therefore return NULL, if the:
- * - publisher is NULL
+/**
+ * This function returns the publisher's internal options struct.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - publisher is `NULL`
* - publisher is invalid (never called init, called fini, or invalid node)
*
* The returned struct is only valid as long as the rcl_publisher_t is valid.
* The values in the struct may change if the options of the publisher change,
* and therefore copying the struct is recommended if this is a concern.
*
- * This function is not thread-safe, and copying the result is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] publisher pointer to the publisher
- * \return options struct if successful, otherwise NULL
+ * \return options struct if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -253,9 +304,10 @@ const rcl_publisher_options_t *
rcl_publisher_get_options(const rcl_publisher_t * publisher);
/// Return the rmw publisher handle.
-/* The handle returned is a pointer to the internally held rmw handle.
- * This function can fail, and therefore return NULL, if the:
- * - publisher is NULL
+/**
+ * The handle returned is a pointer to the internally held rmw handle.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - publisher is `NULL`
* - publisher is invalid (never called init, called fini, or invalid node)
*
* The returned handle is made invalid if the publisher is finalized or if
@@ -266,8 +318,16 @@ rcl_publisher_get_options(const rcl_publisher_t * publisher);
* this function each time it is needed and avoid use of the handle
* concurrently with functions that might change it.
*
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ *
* \param[in] publisher pointer to the rcl publisher
- * \return rmw publisher handle if successful, otherwise NULL
+ * \return rmw publisher handle if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/rcl.h b/rcl/include/rcl/rcl.h
index e742e77..a7cb841 100644
--- a/rcl/include/rcl/rcl.h
+++ b/rcl/include/rcl/rcl.h
@@ -12,6 +12,50 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+/** \mainpage rcl: Common functionality for other ROS Client Libraries
+ *
+ * `rcl` consists of functions and structs (pure C) organized into ROS concepts:
+ *
+ * - Nodes
+ * - rcl/node.h
+ * - Publisher
+ * - rcl/publisher.h
+ * - Subscription
+ * - rcl/subscription.h
+ * - Service Client
+ * - rcl/client.h
+ * - Service Server
+ * - rcl/service.h
+ * - Timer
+ * - rcl/timer.h
+ *
+ * It also has some machinery that is necessary to wait on and act on these concepts:
+ *
+ * - Initialization and shutdown management (global for now)
+ * - rcl/rcl.h
+ * - Wait sets for waiting on messages/service requests and responses/timers to be ready
+ * - rcl/wait.h
+ * - Guard conditions for waking up wait sets asynchronously
+ * - rcl/guard_condition.h
+ * - Functions for introspecting and getting notified of changes of the ROS graph
+ * - rcl/graph.h
+ *
+ * Further still there are some useful abstractions and utilities:
+ *
+ * - Allocator concept, which can used to control allocation in `rcl_*` functions
+ * - rcl/allocator.h
+ * - Concept of ROS Time and access to steady and system wall time
+ * - rcl/time.h
+ * - Error handling functionality (C style)
+ * - rcl/error_handling.h
+ * - Macros
+ * - rcl/macros.h
+ * - Return code types
+ * - rcl/types.h
+ * - Macros for controlling symbol visibility on the library
+ * - rcl/visibility_control.h
+ */
+
#ifndef RCL__RCL_H_
#define RCL__RCL_H_
@@ -29,37 +73,41 @@ extern "C"
#include "rcl/visibility_control.h"
/// Global initialization of rcl.
-/* Unless otherwise noted, this must be called before using any rcl functions.
+/**
+ * Unless otherwise noted, this must be called before using any rcl functions.
*
* This function can only be run once after starting the program, and once
- * after each call to rcl_shutdown.
- * Repeated calls will fail with RCL_RET_ALREADY_INIT.
- * This function is not thread safe.
+ * after each call to rcl_shutdown().
+ * Repeated calls will fail with `RCL_RET_ALREADY_INIT`.
*
- * This function can be called any time after rcl_shutdown is called, but it
+ * This function can be called any time after rcl_shutdown() is called, but it
* cannot be called from within a callback being executed by an rcl executor.
- * For example, you can call rcl_shutdown from within a timer callback, but
+ * For example, you can call rcl_shutdown() from within a timer callback, but
* you have to return from the callback, and therefore exit any in-progress
- * call to a spin function, before calling rcl_init again.
+ * call to a spin function, before calling rcl_init() again.
*
- * The argc and argv parameters can contain command line arguments for the
+ * The `argc` and `argv` parameters can contain command line arguments for the
* program.
* rcl specific arguments will be parsed and removed, but other arguments will
* be ignored.
- * If argc is 0 and argv is NULL no parameters will be parsed.
+ * If `argc` is `0` and `argv` is `NULL` no parameters will be parsed.
*
- * This function allocates heap memory.
- * This function is not thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_uint_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_uint_least64_t`
*
* \param[in] argc number of strings in argv
* \param[in] argv command line arguments; rcl specific arguments are removed
- * \param[in] allocator allocator to be used during rcl_init and rcl_shutdown
- * \return RCL_RET_OK if initialization is successful, or
- * RCL_RET_ALREADY_INIT if rcl_init has already been called, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \param[in] allocator rcl_allocator_t used in rcl_init() and rcl_shutdown()
+ * \return `RCL_RET_OK` if initialization is successful, or
+ * \return `RCL_RET_ALREADY_INIT` if rcl_init has already been called, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -67,28 +115,34 @@ rcl_ret_t
rcl_init(int argc, char ** argv, rcl_allocator_t allocator);
/// Signal global shutdown of rcl.
-/* This function does not have to be called on exit, but does have to be called
- * making a repeat call to rcl_init.
+/**
+ * This function does not have to be called on exit, but does have to be called
+ * making a repeat call to rcl_init().
*
- * This function can only be called once after each call to rcl_init.
+ * This function can only be called once after each call to rcl_init().
* Repeated calls will fail with RCL_RET_NOT_INIT.
* This function is not thread safe.
*
* When this function is called:
- * - Any rcl objects created since the last call to rcl_init are invalidated.
- * - Calls to rcl_ok will return false.
+ * - Any rcl objects created since the last call to rcl_init() are invalidated.
+ * - Calls to rcl_ok() will return `false`.
* - Any executors waiting for work (within a call to spin) are interrupted.
* - No new work (executing callbacks) will be done in executors.
* - Currently running work in executors will be finished.
*
- * This function manipulates heap memory.
- * This function is thread-safe, except with rcl_init().
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_uint_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | Yes [1]
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [2]
+ * [1] not thread-safe with rcl_init()
+ * [2] if `atomic_is_lock_free()` returns true for `atomic_uint_least64_t`
*
- * \return RCL_RET_OK if the shutdown was completed successfully, or
- * RCL_RET_NOT_INIT if rcl is not currently initialized, or
- * RCL_RET_ERROR if an unspecified error occur.
+ * \return `RCL_RET_OK` if the shutdown was completed successfully, or
+ * \return `RCL_RET_NOT_INIT` if rcl is not currently initialized, or
+ * \return `RCL_RET_ERROR` if an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -96,25 +150,34 @@ rcl_ret_t
rcl_shutdown(void);
/// Returns an uint64_t number that is unique for the latest rcl_init call.
-/* If called before rcl_init or after rcl_shutdown then 0 will be returned.
+/**
+ * If called before rcl_init or after rcl_shutdown then 0 will be returned.
*
- * This function does not allocate memory.
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_uint_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_uint_least64_t`
*
- * \return a unique id specific to this rcl instance, or 0 if not initialized.
+ * \return a unique id specific to this rcl instance, or `0` if not initialized.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
uint64_t
rcl_get_instance_id(void);
-/// Return true if rcl is currently initialized, otherwise false.
-/* This function does not allocate memory.
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_uint_least64_t.
+/// Return `true` if rcl is currently initialized, otherwise `false`.
+/**
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_uint_least64_t`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/service.h b/rcl/include/rcl/service.h
index f2ad239..68b1aeb 100644
--- a/rcl/include/rcl/service.h
+++ b/rcl/include/rcl/service.h
@@ -29,7 +29,7 @@ extern "C"
/// Internal rcl implementation struct.
struct rcl_service_impl_t;
-/// Handle for a rcl service.
+/// Structure which encapsulates a ROS Service.
typedef struct rcl_service_t
{
struct rcl_service_impl_t * impl;
@@ -41,15 +41,14 @@ typedef struct rcl_service_options_t
/// Middleware quality of service settings for the service.
rmw_qos_profile_t qos;
/// Custom allocator for the service, used for incidental allocations.
- /* For default behavior (malloc/free), see: rcl_get_default_allocator() */
+ /** For default behavior (malloc/free), see: rcl_get_default_allocator() */
rcl_allocator_t allocator;
} rcl_service_options_t;
-/// Return a rcl_service_t struct with members set to NULL.
-/* Should be called to get a null rcl_service_t before passing to
- * rcl_initalize_service().
- * It's also possible to use calloc() instead of this if the rcl_service_t
- * is being allocated on the heap.
+/// Return a rcl_service_t struct with members set to `NULL`.
+/**
+ * Should be called to get a null rcl_service_t before passing to
+ * rcl_service_init().
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -57,7 +56,8 @@ rcl_service_t
rcl_get_zero_initialized_service(void);
/// Initialize a rcl service.
-/* After calling this function on a rcl_service_t, it can be used to take
+/**
+ * After calling this function on a rcl_service_t, it can be used to take
* requests of the given type to the given topic using rcl_take_request().
* It can also send a response to a request using rcl_send_response().
*
@@ -68,28 +68,31 @@ rcl_get_zero_initialized_service(void);
* When the user defines a ROS service, code is generated which provides the
* required rosidl_service_type_support_t object.
* This object can be obtained using a language appropriate mechanism.
- * \TODO(wjwwood) probably should talk about this once and link to it instead
- * \TODO(jacquelinekay) reworded this for services with substitutions, should it refer to messages?
- * For C this macro can be used (using example_interfaces/AddTwoInts as an example):
+ * \todo TODO(wjwwood) write these instructions once and link to it instead
+ * For C a macro can be used (for example `example_interfaces/AddTwoInts`):
*
- * #include
- * #include
- * rosidl_service_type_support_t * ts =
- * ROSIDL_GET_SERVICE_TYPE_SUPPORT(example_interfaces, AddTwoInts);
+ * ```c
+ * #include
+ * #include
+ * rosidl_service_type_support_t * ts =
+ * ROSIDL_GET_SERVICE_TYPE_SUPPORT(example_interfaces, AddTwoInts);
+ * ```
*
* For C++ a template function is used:
*
- * #include
- * #include
- * rosidl_service_type_support_t * ts = rosidl_generator_cpp::get_service_type_support_handle<
- * example_interfaces::srv::AddTwoInts>();
+ * ```cpp
+ * #include
+ * #include
+ * rosidl_service_type_support_t * ts = rosidl_generator_cpp::get_service_type_support_handle<
+ * example_interfaces::srv::AddTwoInts>();
+ * ```
*
* The rosidl_service_type_support_t object contains service type specific
* information used to send or take requests and responses.
*
- * \TODO(wjwwood) update this once we've come up with an official scheme.
- * The service name must be a non-empty string which follows the service/topic naming
- * format.
+ * \todo TODO(wjwwood) update this once we've come up with an official scheme.
+ * The service name must be a non-empty string which follows the service/topic
+ * naming format.
*
* The options struct allows the user to set the quality of service settings as
* well as a custom allocator which is used when initializing/finalizing the
@@ -97,34 +100,44 @@ rcl_get_zero_initialized_service(void);
*
* Expected usage (for C services):
*
- * #include
- * #include
- * #include
+ * ```c
+ * #include
+ * #include
+ * #include
*
- * rcl_node_t node = rcl_get_zero_initialized_node();
- * rcl_node_options_t node_ops = rcl_node_get_default_options();
- * rcl_ret_t ret = rcl_node_init(&node, "node_name", &node_ops);
- * // ... error handling
- * rosidl_service_type_support_t * ts = ROSIDL_GET_SERVICE_TYPE_SUPPORT(
- * example_interfaces, AddTwoInts);
- * rcl_service_t service = rcl_get_zero_initialized_service();
- * rcl_service_options_t service_ops = rcl_service_get_default_options();
- * ret = rcl_service_init(&service, &node, ts, "add_two_ints", &service_ops);
- * // ... error handling, and on shutdown do finalization:
- * ret = rcl_service_fini(&service, &node);
- * // ... error handling for rcl_service_fini()
- * ret = rcl_node_fini(&node);
- * // ... error handling for rcl_node_fini()
+ * rcl_node_t node = rcl_get_zero_initialized_node();
+ * rcl_node_options_t node_ops = rcl_node_get_default_options();
+ * rcl_ret_t ret = rcl_node_init(&node, "node_name", &node_ops);
+ * // ... error handling
+ * rosidl_service_type_support_t * ts = ROSIDL_GET_SERVICE_TYPE_SUPPORT(
+ * example_interfaces, AddTwoInts);
+ * rcl_service_t service = rcl_get_zero_initialized_service();
+ * rcl_service_options_t service_ops = rcl_service_get_default_options();
+ * ret = rcl_service_init(&service, &node, ts, "add_two_ints", &service_ops);
+ * // ... error handling, and on shutdown do finalization:
+ * ret = rcl_service_fini(&service, &node);
+ * // ... error handling for rcl_service_fini()
+ * ret = rcl_node_fini(&node);
+ * // ... error handling for rcl_node_fini()
+ * ```
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[out] service preallocated service structure
* \param[in] node valid rcl node handle
* \param[in] type_support type support object for the service's type
* \param[in] service_name the name of the service
* \param[in] options service options, including quality of service settings
- * \return RCL_RET_OK if service was initialized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if service was initialized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -137,21 +150,28 @@ rcl_service_init(
const rcl_service_options_t * options);
/// Finalize a rcl_service_t.
-/* After calling, the node will no longer listen for requests for this service.
+/**
+ * After calling, the node will no longer listen for requests for this service.
* (assuming this is the only service of this type in this node).
*
- * After calling, calls to rcl_wait, rcl_take_request, and rcl_send_response will fail when using
- * this service.
- * Additionally rcl_wait will be interrupted if currently blocking.
+ * After calling, calls to rcl_wait(), rcl_take_request(), and
+ * rcl_send_response() will fail when using this service.
+ * Additionally rcl_wait() will be interrupted if currently blocking.
* However, the given node handle is still valid.
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] service handle to the service to be deinitialized
* \param[in] node handle to the node used to create the service
- * \return RCL_RET_OK if service was deinitialized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if service was deinitialized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -159,13 +179,20 @@ rcl_ret_t
rcl_service_fini(rcl_service_t * service, rcl_node_t * node);
/// Return the default service options in a rcl_service_options_t.
+/**
+ * The defaults are:
+ *
+ * - qos = rmw_qos_profile_services_default
+ * - allocator = rcl_get_default_allocator()
+ */
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_service_options_t
rcl_service_get_default_options(void);
/// Take a pending ROS request using a rcl service.
-/* It is the job of the caller to ensure that the type of the ros_request
+/**
+ * It is the job of the caller to ensure that the type of the ros_request
* argument and the type associate with the service, via the type
* support, match.
* Passing a different type to rcl_take produces undefined behavior and cannot
@@ -188,14 +215,23 @@ rcl_service_get_default_options(void);
* request_header is a pointer to pre-allocated a rmw struct containing
* meta-information about the request (e.g. the sequence number).
*
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Maybe [1]
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ * [1] only if required when filling the request, avoided for fixed sizes
+ *
* \param[in] service the handle to the service from which to take
* \param[inout] request_header ptr to the struct holding metadata about the request ID
* \param[inout] ros_request type-erased ptr to an allocated ROS request message
- * \return RCL_RET_OK if the request was taken, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_SERVICE_INVALID if the service is invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the request was taken, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_SERVICE_INVALID` if the service is invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -206,37 +242,49 @@ rcl_take_request(
void * ros_request);
/// Send a ROS response to a client using a service.
-/* It is the job of the caller to ensure that the type of the ros_response
+/**
+ * It is the job of the caller to ensure that the type of the `ros_response`
* parameter and the type associate with the service (via the type support)
* match.
- * Passing a different type to send_response produces undefined behavior and cannot
- * be checked by this function and therefore no deliberate error will occur.
+ * Passing a different type to send_response produces undefined behavior and
+ * cannot be checked by this function and therefore no deliberate error will
+ * occur.
*
- * send_response is an non-blocking call.
+ * send_response() is an non-blocking call.
*
- * The ROS response message given by the ros_response void pointer is always owned by the
- * calling code, but should remain constant during send_response.
+ * The ROS response message given by the `ros_response` void pointer is always
+ * owned by the calling code, but should remain constant during
+ * rcl_send_response().
*
e This function is thread safe so long as access to both the service and the
- * ros_response is synchronized.
- * That means that calling rcl_send_response from multiple threads is allowed, but
- * calling rcl_send_response at the same time as non-thread safe service functions
- * is not, e.g. calling rcl_send_response and rcl_service_fini concurrently
- * is not allowed.
- * Before calling rcl_send_response the message can change and after calling
- * rcl_send_response the message can change, but it cannot be changed during the
- * send_response call.
- * The same ros_response, however, can be passed to multiple calls of
- * rcl_send_response simultaneously, even if the services differ.
- * The ros_response is unmodified by rcl_send_response.
+ * `ros_response` is synchronized.
+ * That means that calling rcl_send_response() from multiple threads is
+ * allowed, but calling rcl_send_response() at the same time as non-thread safe
+ * service functions is not, e.g. calling rcl_send_response() and
+ * rcl_service_fini() concurrently is not allowed.
+ * Before calling rcl_send_response() the message can change and after calling
+ * rcl_send_response() the message can change, but it cannot be changed during
+ * the rcl_send_response() call.
+ * The same `ros_response`, however, can be passed to multiple calls of
+ * rcl_send_response() simultaneously, even if the services differ.
+ * The `ros_response` is unmodified by rcl_send_response().
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes [1]
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ * [1] for unique pairs of services and responses, see above for more
*
* \param[in] service handle to the service which will make the response
* \param[inout] response_header ptr to the struct holding metadata about the request ID
* \param[in] ros_response type-erased pointer to the ROS response message
- * \return RCL_RET_OK if the response was sent successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_SERVICE_INVALID if the service is invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the response was sent successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_SERVICE_INVALID` if the service is invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -247,19 +295,26 @@ rcl_send_response(
void * ros_response);
/// Get the topic name for the service.
-/* This function returns the service's internal topic name string.
- * This function can fail, and therefore return NULL, if the:
- * - service is NULL
+/**
+ * This function returns the service's internal topic name string.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - service is `NULL`
* - service is invalid (never called init, called fini, or invalid)
*
* The returned string is only valid as long as the service is valid.
* The value of the string may change if the topic name changes, and therefore
* copying the string is recommended if this is a concern.
*
- * This function is not thread-safe, and copying the result is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] service the pointer to the service
- * \return name string if successful, otherwise NULL
+ * \return name string if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -267,19 +322,26 @@ const char *
rcl_service_get_service_name(const rcl_service_t * service);
/// Return the rcl service options.
-/* This function returns the service's internal options struct.
- * This function can fail, and therefore return NULL, if the:
- * - service is NULL
+/**
+ * This function returns the service's internal options struct.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - service is `NULL`
* - service is invalid (never called init, called fini, or invalid)
*
* The returned struct is only valid as long as the service is valid.
* The values in the struct may change if the service's options change,
* and therefore copying the struct is recommended if this is a concern.
*
- * This function is not thread-safe, and copying the result is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] service pointer to the service
- * \return options struct if successful, otherwise NULL
+ * \return options struct if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -287,9 +349,10 @@ const rcl_service_options_t *
rcl_service_get_options(const rcl_service_t * service);
/// Return the rmw service handle.
-/* The handle returned is a pointer to the internally held rmw handle.
- * This function can fail, and therefore return NULL, if the:
- * - service is NULL
+/**
+ * The handle returned is a pointer to the internally held rmw handle.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - service is `NULL`
* - service is invalid (never called init, called fini, or invalid)
*
* The returned handle is made invalid if the service is finalized or if
@@ -300,10 +363,16 @@ rcl_service_get_options(const rcl_service_t * service);
* this function each time it is needed and avoid use of the handle
* concurrently with functions that might change it.
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] service pointer to the rcl service
- * \return rmw service handle if successful, otherwise NULL
+ * \return rmw service handle if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/subscription.h b/rcl/include/rcl/subscription.h
index e6e6d2f..55a596b 100644
--- a/rcl/include/rcl/subscription.h
+++ b/rcl/include/rcl/subscription.h
@@ -29,7 +29,7 @@ extern "C"
/// Internal rcl implementation struct.
struct rcl_subscription_impl_t;
-/// Handle for a rcl subscription.
+/// Structure which encapsulates a ROS Subscription.
typedef struct rcl_subscription_t
{
struct rcl_subscription_impl_t * impl;
@@ -43,15 +43,14 @@ typedef struct rcl_subscription_options_t
/// If true, messages published from within the same node are ignored.
bool ignore_local_publications;
/// Custom allocator for the subscription, used for incidental allocations.
- /* For default behavior (malloc/free), see: rcl_get_default_allocator() */
+ /** For default behavior (malloc/free), see: rcl_get_default_allocator() */
rcl_allocator_t allocator;
} rcl_subscription_options_t;
-/// Return a rcl_subscription_t struct with members set to NULL.
-/* Should be called to get a null rcl_subscription_t before passing to
- * rcl_initalize_subscription().
- * It's also possible to use calloc() instead of this if the rcl_subscription_t
- * is being allocated on the heap.
+/// Return a rcl_subscription_t struct with members set to `NULL`.
+/**
+ * Should be called to get a null rcl_subscription_t before passing to
+ * rcl_subscription_init().
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -59,7 +58,8 @@ rcl_subscription_t
rcl_get_zero_initialized_subscription(void);
/// Initialize a ROS subscription.
-/* After calling this function on a rcl_subscription_t, it can be used to take
+/**
+ * After calling this function on a rcl_subscription_t, it can be used to take
* messages of the given type to the given topic using rcl_take().
*
* The given rcl_node_t must be valid and the resulting rcl_subscription_t is
@@ -69,25 +69,29 @@ rcl_get_zero_initialized_subscription(void);
* When the user defines a ROS message, code is generated which provides the
* required rosidl_message_type_support_t object.
* This object can be obtained using a language appropriate mechanism.
- * \TODO(wjwwood) probably should talk about this once and link to it instead
- * For C this macro can be used (using std_msgs/String as an example):
+ * \todo TODO(wjwwood) write these instructions once and link to it instead
+ * For C a macro can be used (for example `std_msgs/String`):
*
- * #include
- * #include
- * rosidl_message_type_support_t * string_ts =
- * ROSIDL_GET_MESSAGE_TYPE_SUPPORT(std_msgs, String);
+ * ```c
+ * #include
+ * #include
+ * rosidl_message_type_support_t * string_ts =
+ * ROSIDL_GET_MESSAGE_TYPE_SUPPORT(std_msgs, String);
+ * ```
*
* For C++ a template function is used:
*
- * #include
- * #include
- * rosidl_message_type_support_t * string_ts =
- * rosidl_generator_cpp::get_message_type_support_handle();
+ * ```cpp
+ * #include
+ * #include
+ * rosidl_message_type_support_t * string_ts =
+ * rosidl_generator_cpp::get_message_type_support_handle();
+ * ```
*
* The rosidl_message_type_support_t object contains message type specific
* information used to publish messages.
*
- * \TODO(wjwwood) update this once we've come up with an official scheme.
+ * \todo TODO(wjwwood) update this once we've come up with an official scheme.
* The topic name must be a non-empty string which follows the topic naming
* format.
*
@@ -98,35 +102,43 @@ rcl_get_zero_initialized_subscription(void);
*
* Expected usage (for C messages):
*
- * #include
- * #include
- * #include
+ * ```c
+ * #include
+ * #include
+ * #include
*
- * rcl_node_t node = rcl_get_zero_initialized_node();
- * rcl_node_options_t node_ops = rcl_node_get_default_options();
- * rcl_ret_t ret = rcl_node_init(&node, "node_name", &node_ops);
- * // ... error handling
- * rosidl_message_type_support_t * ts = ROSIDL_GET_MESSAGE_TYPE_SUPPORT(std_msgs, String);
- * rcl_subscription_t subscription = rcl_get_zero_initialized_subscription();
- * rcl_subscription_options_t subscription_ops = rcl_subscription_get_default_options();
- * ret = rcl_subscription_init(&subscription, &node, ts, "chatter", &subscription_ops);
- * // ... error handling, and when finished deinitialization
- * ret = rcl_subscription_fini(&subscription, &node);
- * // ... error handling for rcl_subscription_fini()
- * ret = rcl_node_fini(&node);
- * // ... error handling for rcl_node_fini()
+ * rcl_node_t node = rcl_get_zero_initialized_node();
+ * rcl_node_options_t node_ops = rcl_node_get_default_options();
+ * rcl_ret_t ret = rcl_node_init(&node, "node_name", &node_ops);
+ * // ... error handling
+ * rosidl_message_type_support_t * ts = ROSIDL_GET_MESSAGE_TYPE_SUPPORT(std_msgs, String);
+ * rcl_subscription_t subscription = rcl_get_zero_initialized_subscription();
+ * rcl_subscription_options_t subscription_ops = rcl_subscription_get_default_options();
+ * ret = rcl_subscription_init(&subscription, &node, ts, "chatter", &subscription_ops);
+ * // ... error handling, and when finished deinitialization
+ * ret = rcl_subscription_fini(&subscription, &node);
+ * // ... error handling for rcl_subscription_fini()
+ * ret = rcl_node_fini(&node);
+ * // ... error handling for rcl_node_fini()
+ * ```
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[out] subscription preallocated subscription structure
* \param[in] node valid rcl node handle
* \param[in] type_support type support object for the topic's type
* \param[in] topic_name the name of the topic
* \param[in] options subscription options, including quality of service settings
- * \return RCL_RET_OK if subscription was initialized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if subscription was initialized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -139,7 +151,8 @@ rcl_subscription_init(
const rcl_subscription_options_t * options);
/// Finalize a rcl_subscription_t.
-/* After calling, the node will no longer be subscribed on this topic
+/**
+ * After calling, the node will no longer be subscribed on this topic
* (assuming this is the only subscription on this topic in this node).
*
* After calling, calls to rcl_wait and rcl_take will fail when using this
@@ -147,13 +160,19 @@ rcl_subscription_init(
* Additioanlly rcl_wait will be interrupted if currently blocking.
* However, the given node handle is still valid.
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] subscription handle to the subscription to be deinitialized
* \param[in] node handle to the node used to create the subscription
- * \return RCL_RET_OK if subscription was deinitialized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if subscription was deinitialized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -161,13 +180,21 @@ rcl_ret_t
rcl_subscription_fini(rcl_subscription_t * subscription, rcl_node_t * node);
/// Return the default subscription options in a rcl_subscription_options_t.
+/**
+ * The defaults are:
+ *
+ * - ignore_local_publications = false
+ * - qos = rmw_qos_profile_default
+ * - allocator = rcl_get_default_allocator()
+ */
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_subscription_options_t
rcl_subscription_get_default_options(void);
/// Take a ROS message from a topic using a rcl subscription.
-/* It is the job of the caller to ensure that the type of the ros_message
+/**
+ * It is the job of the caller to ensure that the type of the ros_message
* argument and the type associate with the subscription, via the type
* support, match.
* Passing a different type to rcl_take produces undefined behavior and cannot
@@ -193,18 +220,27 @@ rcl_subscription_get_default_options(void);
* process.
* The message_info argument should be an already allocated rmw_message_info_t
* structure.
- * Passing NULL for message_info will result in the argument being ignored.
+ * Passing `NULL` for message_info will result in the argument being ignored.
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Maybe [1]
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ * [1] only if required when filling the message, avoided for fixed sizes
*
* \param[in] subscription the handle to the subscription from which to take
* \param[inout] ros_message type-erased ptr to a allocated ROS message
* \param[out] message_info rmw struct which contains meta-data for the message
- * \return RCL_RET_OK if the message was published, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_SUBSCRIPTION_INVALID if the subscription is invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_SUBSCRIPTION_TAKE_FAILED if take failed but no error
+ * \return `RCL_RET_OK` if the message was published, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_SUBSCRIPTION_INVALID` if the subscription is invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_SUBSCRIPTION_TAKE_FAILED` if take failed but no error
* occurred in the middleware, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -215,19 +251,26 @@ rcl_take(
rmw_message_info_t * message_info);
/// Get the topic name for the subscription.
-/* This function returns the subscription's internal topic name string.
- * This function can fail, and therefore return NULL, if the:
- * - subscription is NULL
+/**
+ * This function returns the subscription's internal topic name string.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - subscription is `NULL`
* - subscription is invalid (never called init, called fini, or invalid)
*
* The returned string is only valid as long as the subscription is valid.
* The value of the string may change if the topic name changes, and therefore
* copying the string is recommended if this is a concern.
*
- * This function is not thread-safe, and copying the result is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] subscription the pointer to the subscription
- * \return name string if successful, otherwise NULL
+ * \return name string if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -235,19 +278,26 @@ const char *
rcl_subscription_get_topic_name(const rcl_subscription_t * subscription);
/// Return the rcl subscription options.
-/* This function returns the subscription's internal options struct.
- * This function can fail, and therefore return NULL, if the:
- * - subscription is NULL
+/**
+ * This function returns the subscription's internal options struct.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - subscription is `NULL`
* - subscription is invalid (never called init, called fini, or invalid)
*
* The returned struct is only valid as long as the subscription is valid.
* The values in the struct may change if the subscription's options change,
* and therefore copying the struct is recommended if this is a concern.
*
- * This function is not thread-safe, and copying the result is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] subscription pointer to the subscription
- * \return options struct if successful, otherwise NULL
+ * \return options struct if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -255,9 +305,10 @@ const rcl_subscription_options_t *
rcl_subscription_get_options(const rcl_subscription_t * subscription);
/// Return the rmw subscription handle.
-/* The handle returned is a pointer to the internally held rmw handle.
- * This function can fail, and therefore return NULL, if the:
- * - subscription is NULL
+/**
+ * The handle returned is a pointer to the internally held rmw handle.
+ * This function can fail, and therefore return `NULL`, if the:
+ * - subscription is `NULL`
* - subscription is invalid (never called init, called fini, or invalid)
*
* The returned handle is made invalid if the subscription is finalized or if
@@ -268,10 +319,16 @@ rcl_subscription_get_options(const rcl_subscription_t * subscription);
* this function each time it is needed and avoid use of the handle
* concurrently with functions that might change it.
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] subscription pointer to the rcl subscription
- * \return rmw subscription handle if successful, otherwise NULL
+ * \return rmw subscription handle if successful, otherwise `NULL`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/time.h b/rcl/include/rcl/time.h
index edf990e..7025f25 100644
--- a/rcl/include/rcl/time.h
+++ b/rcl/include/rcl/time.h
@@ -24,14 +24,26 @@ extern "C"
#include "rcl/types.h"
#include "rcl/visibility_control.h"
+/// Convenience macro to convert seconds to nanoseconds.
#define RCL_S_TO_NS(seconds) (seconds * (1000 * 1000 * 1000))
+/// Convenience macro to convert milliseconds to nanoseconds.
#define RCL_MS_TO_NS(milliseconds) (milliseconds * (1000 * 1000))
+/// Convenience macro to convert microseconds to nanoseconds.
#define RCL_US_TO_NS(microseconds) (microseconds * 1000)
+/// Convenience macro to convert nanoseconds to seconds.
#define RCL_NS_TO_S(nanoseconds) (nanoseconds / (1000 * 1000 * 1000))
+/// Convenience macro to convert nanoseconds to milliseconds.
#define RCL_NS_TO_MS(nanoseconds) (nanoseconds / (1000 * 1000))
+/// Convenience macro to convert nanoseconds to microseconds.
#define RCL_NS_TO_US(nanoseconds) (nanoseconds / 1000)
+/// A single point in time, measured in nanoseconds since the Unix epoch.
+typedef uint64_t rcl_time_point_value_t;
+/// A duration of time, measured in nanoseconds.
+typedef int64_t rcl_duration_value_t;
+
+/// Time source type, used to indicate the source of a time measurement.
enum rcl_time_source_type_t
{
RCL_TIME_SOURCE_UNINITIALIZED = 0,
@@ -40,9 +52,7 @@ enum rcl_time_source_type_t
RCL_STEADY_TIME
};
-typedef uint64_t rcl_time_point_value_t;
-typedef int64_t rcl_duration_value_t;
-
+/// Encapsulation of a time source.
typedef struct rcl_time_source_t
{
enum rcl_time_source_type_t type;
@@ -54,12 +64,15 @@ typedef struct rcl_time_source_t
} rcl_time_source_t;
struct rcl_ros_time_source_storage_t;
+
+/// A single point in time, measured in nanoseconds, the reference point is based on the source.
typedef struct rcl_time_point_t
{
rcl_time_point_value_t nanoseconds;
rcl_time_source_t * time_source;
} rcl_time_point_t;
+/// A duration of time, measured in nanoseconds and its source.
typedef struct rcl_duration_t
{
rcl_duration_value_t nanoseconds;
@@ -75,7 +88,8 @@ typedef struct rcl_duration_t
// TODO(tfoote) integrate rate and timer implementations
/// Check if the time_source has valid values.
-/* This function returns true if the time source appears to be valid.
+/**
+ * This function returns true if the time source appears to be valid.
* It will check that the type is not uninitialized, and that pointers
* are not invalid.
* Note that if data is uninitialized it may give a false positive.
@@ -88,93 +102,99 @@ RCL_WARN_UNUSED
bool
rcl_time_source_valid(rcl_time_source_t * time_source);
-/// Initialize a timesource as a RCL_ROS_TIME time source.
-/* This will allocate all necessary internal structures, and initialize variables.
+/// Initialize a time_source as a RCL_ROS_TIME time source.
+/**
+ * This will allocate all necessary internal structures, and initialize variables.
* It is specifically setting up a RCL_ROS_TIME time source.
*
* \param[in] time_source the handle to the time_source which is being initialized
- * \return RCL_RET_OK if the time source was successfully initialized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was successfully initialized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_init_ros_time_source(rcl_time_source_t * time_source);
-/// Finalize a timesource as a RCL_ROS_TIME time source.
-/* This will deallocate all necessary internal structures, and clean up any variables.
- * It is specifically setting up a RCL_ROS_TIME time source. It is expected to be paired with
- * the init fuction.
+/// Finalize a time_source as a `RCL_ROS_TIME` time source.
+/**
+ * This will deallocate all necessary internal structures, and clean up any variables.
+ * It is specifically setting up a `RCL_ROS_TIME` time source. It is expected
+ * to be paired with the init fuction.
*
* \param[in] time_source the handle to the time_source which is being initialized
- * \return RCL_RET_OK if the time source was successfully finalized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was successfully finalized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_fini_ros_time_source(rcl_time_source_t * time_source);
-/// Initialize a timesource as a RCL_STEADY_TIME time source.
-/* This will allocate all necessary internal structures, and initialize variables.
- * It is specifically setting up a RCL_STEADY_TIME time source.
+/// Initialize a time_source as a `RCL_STEADY_TIME` time source.
+/**
+ * This will allocate all necessary internal structures, and initialize variables.
+ * It is specifically setting up a `RCL_STEADY_TIME` time source.
*
* \param[in] time_source the handle to the time_source which is being initialized
- * \return RCL_RET_OK if the time source was successfully initialized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was successfully initialized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_init_steady_time_source(rcl_time_source_t * time_source);
-/// Finalize a timesource as a RCL_STEADY_TIME time source.
-/* Finalize the timesource as a RCL_STEADY_TIME time source.
+/// Finalize a time_source as a `RCL_STEADY_TIME` time source.
+/**
+ * Finalize the time_source as a `RCL_STEADY_TIME` time source.
*
* This will deallocate all necessary internal structures, and clean up any variables.
- * It is specifically setting up a steady time source. It is expected to be paired with
- * the init fuction.
+ * It is specifically setting up a steady time source. It is expected to be
+ * paired with the init fuction.
*
* \param[in] time_source the handle to the time_source which is being initialized
- * \return RCL_RET_OK if the time source was successfully finalized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was successfully finalized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_fini_steady_time_source(rcl_time_source_t * time_source);
-/// Initialize a timesource as a RCL_SYSTEM_TIME time source.
-/* Initialize the timesource as a RCL_SYSTEM_TIME time source.
+/// Initialize a time_source as a `RCL_SYSTEM_TIME` time source.
+/**
+ * Initialize the time_source as a `RCL_SYSTEM_TIME` time source.
*
* This will allocate all necessary internal structures, and initialize variables.
* It is specifically setting up a system time source.
*
* \param[in] time_source the handle to the time_source which is being initialized
- * \return RCL_RET_OK if the time source was successfully initialized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was successfully initialized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_init_system_time_source(rcl_time_source_t * time_source);
-/// Finalize a timesource as a RCL_SYSTEM_TIME time source.
-/* Finalize the timesource as a RCL_SYSTEM_TIME time source.
+/// Finalize a time_source as a `RCL_SYSTEM_TIME` time source.
+/**
+ * Finalize the time_source as a `RCL_SYSTEM_TIME` time source.
*
* This will deallocate all necessary internal structures, and clean up any variables.
* It is specifically setting up a system time source. It is expected to be paired with
* the init fuction.
*
* \param[in] time_source the handle to the time_source which is being initialized.
- * \return RCL_RET_OK if the time source was successfully finalized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was successfully finalized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -182,18 +202,20 @@ rcl_ret_t
rcl_fini_system_time_source(rcl_time_source_t * time_source);
/// Initialize a time point using the time_source.
-/* This function will initialize the time_point using the time_source
+/**
+ * This function will initialize the time_point using the time_source
* as a reference.
* If the time_source is null it will use the system default time_source.
*
* This will allocate all necessary internal structures, and initialize variables.
- * The time_source may be of types RCL_ROS_TIME, RCL_STEADY_TIME, or RCL_SYSTEM_TIME.
+ * The time_source may be of types `RCL_ROS_TIME`, `RCL_STEADY_TIME`, or
+ * `RCL_SYSTEM_TIME`.
*
* \param[in] time_point the handle to the time_source which is being initialized.
* \param[in] time_source the handle to the time_source will be used for reference.
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -201,14 +223,15 @@ rcl_ret_t
rcl_init_time_point(rcl_time_point_t * time_point, rcl_time_source_t * time_source);
/// Finalize a time_point
-/* Finalize the time_point such that it is ready for deallocation.
+/**
+ * Finalize the time_point such that it is ready for deallocation.
*
* This will deallocate all necessary internal structures, and clean up any variables.
*
* \param[in] time_point the handle to the time_source which is being finalized.
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -216,7 +239,8 @@ rcl_ret_t
rcl_fini_time_point(rcl_time_point_t * time_point);
/// Initialize a duration using the time_source.
-/* This function will initialize the duration using the time_source as a reference.
+/**
+ * This function will initialize the duration using the time_source as a reference.
* If the time_source is null it will use the system default time_source.
*
* This will allocate all necessary internal structures, and initialize variables.
@@ -224,9 +248,9 @@ rcl_fini_time_point(rcl_time_point_t * time_point);
*
* \param[in] duration the handle to the duration which is being initialized.
* \param[in] time_source the handle to the time_source will be used for reference.
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -234,22 +258,24 @@ rcl_ret_t
rcl_init_duration(rcl_duration_t * duration, rcl_time_source_t * time_source);
/// Finalize a duration
-/* Finalize the duration such that it is ready for deallocation.
+/**
+ * Finalize the duration such that it is ready for deallocation.
*
* This will deallocate all necessary internal structures, and clean up any variables.
*
* \param[in] duration the handle to the duration which is being finalized.
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_fini_duration(rcl_duration_t * duration);
-/// Get the default RCL_ROS_TIME time source
-/* This function will get the process default time source.
+/// Get the default `RCL_ROS_TIME` time source
+/**
+ * This function will get the process default time source.
* This time source is specifically of the ROS time abstraction,
* and may be overridden by updates.
*
@@ -264,8 +290,9 @@ RCL_WARN_UNUSED
rcl_time_source_t *
rcl_get_default_ros_time_source(void);
-/// Get the default RCL_STEADY_TIME time source
-/* This function will get the process default time source.
+/// Get the default `RCL_STEADY_TIME` time source
+/**
+ * This function will get the process default time source.
* This time source is specifically of the steady time abstraction,
* it should not be able to be overridden..
*
@@ -280,8 +307,9 @@ RCL_WARN_UNUSED
rcl_time_source_t *
rcl_get_default_steady_time_source(void);
-/// Get the default RCL_SYSTEM_TIME time source
-/* This function will get the process default time source.
+/// Get the default `RCL_SYSTEM_TIME` time source
+/**
+ * This function will get the process default time source.
* This time source is specifically of the system time abstraction,
* and may be overridden by updates to the system clock.
*
@@ -296,19 +324,20 @@ RCL_WARN_UNUSED
rcl_time_source_t *
rcl_get_default_system_time_source(void);
-/// Set the current time on the RCL_ROS_TIME time source
-/* This function is used to set the time on a ros time source.
- * It will error if passed a differnt time source.
+/// Set the current time on the `RCL_ROS_TIME` time source
+/**
+ * This function is used to set the time on a ROS time source.
+ * It will error if passed a different time source.
*
* This should not block, except on Windows. One caveat is that
- * if the ros time abstraction is active, it will invoke the user
+ * if the ROS time abstraction is active, it will invoke the user
* defined callbacks, for pre and post update notifications. The
- * calbacks are supposed to be short running and non-blocking.
+ * callbacks are supposed to be short running and non-blocking.
*
* \param[in] process_time_source The time source on which to set the value.
- * \return RCL_RET_OK if the value was set successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the value was set successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -316,7 +345,8 @@ rcl_ret_t
rcl_set_default_ros_time_source(rcl_time_source_t * process_time_source);
/// Compute the difference between two time points
-/* This function takes two time points and computes the duration between them.
+/**
+ * This function takes two time points and computes the duration between them.
* The two time points must be using the same time abstraction, and the
* resultant duration will also be of the same abstraction.
*
@@ -326,9 +356,9 @@ rcl_set_default_ros_time_source(rcl_time_source_t * process_time_source);
* \param[in] start The time point for the start of the duration.
* \param[in] finish The time point for the end of the duration.
* \param[out] delta The duration between the start and finish.
- * \return RCL_RET_OK if the difference was computed successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the difference was computed successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -337,13 +367,14 @@ rcl_difference_times(rcl_time_point_t * start, rcl_time_point_t * finish,
rcl_duration_t * delta);
/// Fill the time point with the current value of the associated clock.
-/* This function will populate the data of the time_point object with the
+/**
+ * This function will populate the data of the time_point object with the
* current value from it's associated time abstraction.
*
* \param[out] time_point The time_point to populate.
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -351,30 +382,32 @@ rcl_ret_t
rcl_get_time_point_now(rcl_time_point_t * time_point);
-/// Enable the ros time abstraction override.
-/* This method will enable the ros time abstraction override values,
+/// Enable the ROS time abstraction override.
+/**
+ * This method will enable the ROS time abstraction override values,
* such that the time source will report the set value instead of falling
* back to system time.
*
* \param[in] time_source The time_source to enable.
- * \return RCL_RET_OK if the time source was enabled successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was enabled successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_enable_ros_time_override(rcl_time_source_t * time_source);
-/// Disable the ros time abstraction override.
-/* This method will disable the RCL_ROS_TIME time abstraction override values,
+/// Disable the ROS time abstraction override.
+/**
+ * This method will disable the `RCL_ROS_TIME` time abstraction override values,
* such that the time source will report the system time even if a custom
* value has been set.
*
* \param[in] time_source The time_source to disable.
- * \return RCL_RET_OK if the time source was disabled successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was disabled successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -382,16 +415,17 @@ rcl_ret_t
rcl_disable_ros_time_override(rcl_time_source_t * time_source);
-/// Check if the RCL_ROS_TIME time source has the override enabled.
-/* This will populate the is_enabled object to indicate if the
+/// Check if the `RCL_ROS_TIME` time source has the override enabled.
+/**
+ * This will populate the is_enabled object to indicate if the
* time overide is enabled. If it is enabled, the set value will be returned.
* Otherwise this time source will return the equivalent to system time abstraction.
*
* \param[in] time_source The time_source to query.
* \param[out] is_enabled Whether the override is enabled..
- * \return RCL_RET_OK if the time source was queried successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was queried successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -399,16 +433,18 @@ rcl_ret_t
rcl_is_enabled_ros_time_override(rcl_time_source_t * time_source,
bool * is_enabled);
-/// Set the current time for this RCL_ROS_TIME time source.
-/* This function will update the internal storage for the RCL_ROS_TIME time source.
+/// Set the current time for this `RCL_ROS_TIME` time source.
+/**
+ * This function will update the internal storage for the `RCL_ROS_TIME`
+ * time source.
* If queried and override enabled the time source will return this value,
* otherwise it will return the system time.
*
* \param[in] time_source The time_source to update.
* \param[in] time_value The new current time.
- * \return RCL_RET_OK if the time source was set successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the time source was set successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -416,8 +452,9 @@ rcl_ret_t
rcl_set_ros_time_override(rcl_time_source_t * time_source,
rcl_time_point_value_t time_value);
-/// Retrieve the current time as a rcl_time_point_value_t (an alias for unint64_t).
-/* This function returns the time from a system clock.
+/// Retrieve the current time as a rcl_time_point_value_t.
+/**
+ * This function returns the time from a system clock.
* The closest equivalent would be to std::chrono::system_clock::now();
*
* The resolution (e.g. nanoseconds vs microseconds) is not guaranteed.
@@ -425,27 +462,30 @@ rcl_set_ros_time_override(rcl_time_source_t * time_source,
* The now argument must point to an allocated rcl_system_time_point_t struct,
* as the result is copied into this variable.
*
- * This function may allocate heap memory when an error occurs.
- * This function is thread-safe.
- * This function is lock-free, with an exception on Windows.
- * On Windows this is lock-free if the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_int_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | No
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
- * TODO(tfoote): I talked with @wjwwood about possibly promoting this
- * method into rmw for more reuse.
+ * \todo TODO(tfoote): consider moving this to rmw for more reuse
*
* \param[out] now a datafield in which the current time is stored
- * \return RCL_RET_OK if the current time was successfully obtained, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the current time was successfully obtained, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_system_time_now(rcl_time_point_value_t * now);
-/// Retrieve the current time as a rcl_time_point_value_t object..
-/* This function returns the time from a monotonically increasing clock.
+/// Retrieve the current time as a rcl_time_point_value_t object.
+/**
+ * This function returns the time from a monotonically increasing clock.
* The closest equivalent would be to std::chrono::steady_clock::now();
*
* The resolution (e.g. nanoseconds vs microseconds) is not guaranteed.
@@ -453,19 +493,21 @@ rcl_system_time_now(rcl_time_point_value_t * now);
* The now argument must point to an allocated rcl_time_point_value_t object,
* as the result is copied into this variable.
*
- * This function may allocate heap memory when an error occurs.
- * This function is thread-safe.
- * This function is lock-free, with an exception on Windows.
- * On Windows this is lock-free if the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_int_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | No
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
- * TODO(tfoote) I talked with @wjwwood about possibly promoting this
- * method into rmw for more reuse.
+ * \todo TODO(tfoote): consider moving this to rmw for more reuse
*
* \param[out] now a struct in which the current time is stored
- * \return RCL_RET_OK if the current time was successfully obtained, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the current time was successfully obtained, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/timer.h b/rcl/include/rcl/timer.h
index 4f3567c..ffca244 100644
--- a/rcl/include/rcl/timer.h
+++ b/rcl/include/rcl/timer.h
@@ -30,7 +30,7 @@ extern "C"
struct rcl_timer_impl_t;
-/// Handle for a ROS timer.
+/// Structure which encapsulates a ROS Timer.
typedef struct rcl_timer_t
{
/// Private implementation pointer.
@@ -38,12 +38,14 @@ typedef struct rcl_timer_t
} rcl_timer_t;
/// User callback signature for timers.
-/* The first argument the callback gets is a pointer to the timer.
+/**
+ * The first argument the callback gets is a pointer to the timer.
* This can be used to cancel the timer, query the time until the next
* timer callback, exchange the callback with a different one, etc.
*
- * The only caveat is that the function rcl_timer_get_time_since_last_call will
- * return the time since just before this callback was called, not the last.
+ * The only caveat is that the function rcl_timer_get_time_since_last_call()
+ * will return the time since just before this callback was called, not the
+ * previous call.
* Therefore the second argument given is the time since the previous callback
* was called, because that information is no longer accessible via the timer.
* The time since the last callback call is given in nanoseconds.
@@ -57,7 +59,8 @@ rcl_timer_t
rcl_get_zero_initialized_timer(void);
/// Initialize a timer.
-/* A timer consists of a callback function and a period.
+/**
+ * A timer consists of a callback function and a period.
* A timer can be added to a wait set and waited on, such that the wait set
* will wake up when a timer is ready to be executed.
*
@@ -75,12 +78,12 @@ rcl_get_zero_initialized_timer(void);
* zero initialized is undefined behavior.
*
* The period is a duration (rather an absolute time in the future).
- * If the period is 0 then it will always be ready.
+ * If the period is `0` then it will always be ready.
*
* The callback is an optional argument.
- * Valid inputs are either a pointer to the function callback, or NULL to
+ * Valid inputs are either a pointer to the function callback, or `NULL` to
* indicate that no callback will be stored in rcl.
- * If the callback is null, the caller client library is responsible for
+ * If the callback is `NULL`, the caller client library is responsible for
* firing the timer callback.
* Else, it must be a function which returns void and takes two arguments,
* the first being a pointer to the associated timer, and the second a uint64_t
@@ -89,34 +92,45 @@ rcl_get_zero_initialized_timer(void);
*
* Expected usage:
*
- * #include
+ * ```c
+ * #include
*
- * void my_timer_callback(rcl_timer_t * timer, uint64_t last_call_time)
- * {
- * // Do timer work...
- * // Optionally reconfigure, cancel, or reset the timer...
- * }
+ * void my_timer_callback(rcl_timer_t * timer, uint64_t last_call_time)
+ * {
+ * // Do timer work...
+ * // Optionally reconfigure, cancel, or reset the timer...
+ * }
*
- * rcl_timer_t timer = rcl_get_zero_initialized_timer();
- * rcl_ret_t ret =
- * rcl_timer_init(&timer, RCL_MS_TO_NS(100), my_timer_callback, rcl_get_default_allocator());
- * // ... error handling, use the timer with a wait set, or poll it manually, then cleanup
- * ret = rcl_timer_fini(&timer);
- * // ... error handling
+ * rcl_timer_t timer = rcl_get_zero_initialized_timer();
+ * rcl_ret_t ret = rcl_timer_init(
+ * &timer, RCL_MS_TO_NS(100), my_timer_callback, rcl_get_default_allocator());
+ * // ... error handling, use the timer with a wait set, or poll it manually, then cleanup
+ * ret = rcl_timer_fini(&timer);
+ * // ... error handling
+ * ```
*
- * This function does allocate heap memory.
- * This function is not thread-safe.
- * This function is not lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1][2][3]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_uintptr_t`
+ *
+ * [2] if `atomic_is_lock_free()` returns true for `atomic_uint_least64_t`
+ *
+ * [3] if `atomic_is_lock_free()` returns true for `atomic_bool`
*
* \param[inout] timer the timer handle to be initialized
* \param[in] period the duration between calls to the callback in nanoseconds
* \param[in] callback the user defined function to be called every period
* \param[in] allocator the allocator to use for allocations
- * \return RCL_RET_OK if the timer was initialized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ALREADY_INIT if the timer was already initialized, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the timer was initialized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ALREADY_INIT` if the timer was already initialized, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -128,20 +142,30 @@ rcl_timer_init(
rcl_allocator_t allocator);
/// Finalize a timer.
-/* This function will deallocate any memory and make the timer invalid.
+/**
+ * This function will deallocate any memory and make the timer invalid.
*
- * A timer that is already invalid (zero initialized) or NULL will not fail.
+ * A timer that is already invalid (zero initialized) or `NULL` will not fail.
*
* This function is not thread-safe with any rcl_timer_* functions used on the
* same timer object.
*
- * This function may allocate heap memory when an error occurs.
- * This function is not thread-safe.
- * This function is not lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1][2][3]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_uintptr_t`
+ *
+ * [2] if `atomic_is_lock_free()` returns true for `atomic_uint_least64_t`
+ *
+ * [3] if `atomic_is_lock_free()` returns true for `atomic_bool`
*
* \param[inout] timer the handle to the timer to be finalized.
- * \return RCL_RET_OK if the timer was finalized successfully, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the timer was finalized successfully, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -149,11 +173,12 @@ rcl_ret_t
rcl_timer_fini(rcl_timer_t * timer);
/// Call the timer's callback and set the last call time.
-/* This function will call the callback and change the last call time even if
+/**
+ * This function will call the callback and change the last call time even if
* the timer's period has not yet elapsed.
* It is up to the calling code to make sure the period has elapsed by first
* calling rcl_timer_is_ready().
- * If the callback pointer is null (either set in init or exchanged after
+ * If the callback pointer is `NULL` (either set in init or exchanged after
* initialized), no callback is fired.
* However, this function should still be called by the client library to
* update the state of the timer.
@@ -168,18 +193,23 @@ rcl_timer_fini(rcl_timer_t * timer);
* During the callback the timer can be canceled or have its period and/or
* callback modified.
*
- * This function may allocate heap memory when an error occurs.
- * This function is thread-safe, but the user's callback may not be.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_int_least64_t, but the user's
- * callback may not be lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes [1]
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [2]
+ * [1] user callback might not be thread-safe
+ *
+ * [2] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[inout] timer the handle to the timer to call
- * \return RCL_RET_OK if the timer was called successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_TIMER_INVALID if the timer is invalid, or
- * RCL_RET_TIMER_CANCELED if the timer has been canceled, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the timer was called successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_TIMER_INVALID` if the timer is invalid, or
+ * \return `RCL_RET_TIMER_CANCELED` if the timer has been canceled, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -187,24 +217,29 @@ rcl_ret_t
rcl_timer_call(rcl_timer_t * timer);
/// Calculates whether or not the timer should be called.
-/* The result is true if the time until next call is less than, or equal to, 0
+/**
+ * The result is true if the time until next call is less than, or equal to, 0
* and the timer has not been canceled.
* Otherwise the result is false, indicating the timer should not be called.
*
* The is_ready argument must point to an allocated bool object, as the result
* is copied into it.
*
- * This function may allocate heap memory when an error occurs.
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_int_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[in] timer the handle to the timer which is being checked
* \param[out] is_ready the bool used to store the result of the calculation
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_TIMER_INVALID if the timer is invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_TIMER_INVALID` if the timer is invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -212,7 +247,8 @@ rcl_ret_t
rcl_timer_is_ready(const rcl_timer_t * timer, bool * is_ready);
/// Calculate and retrieve the time until the next call in nanoseconds.
-/* This function calculates the time until the next call by adding the timer's
+/**
+ * This function calculates the time until the next call by adding the timer's
* period to the last call time and subtracting that sum from the current time.
* The calculated time until the next call can be positive, indicating that it
* is not ready to be called as the period has not elapsed since the last call.
@@ -221,20 +257,24 @@ rcl_timer_is_ready(const rcl_timer_t * timer, bool * is_ready);
* should be called.
* A negative value indicates the timer call is overdue by that amount.
*
- * The time_until_next_call argument must point to an allocated int64_t, as the
- * the time until is coped into that instance.
+ * The `time_until_next_call` argument must point to an allocated int64_t, as
+ * the time until is copied into that instance.
*
- * This function may allocate heap memory when an error occurs.
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_int_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[in] timer the handle to the timer that is being queried
* \param[out] time_until_next_call the output variable for the result
- * \return RCL_RET_OK if the timer until next call was successfully calculated, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_TIMER_INVALID if the timer is invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the timer until next call was successfully calculated, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_TIMER_INVALID` if the timer is invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -242,7 +282,8 @@ rcl_ret_t
rcl_timer_get_time_until_next_call(const rcl_timer_t * timer, int64_t * time_until_next_call);
/// Retrieve the time since the previous call to rcl_timer_call() occurred.
-/* This function calculates the time since the last call and copies it into
+/**
+ * This function calculates the time since the last call and copies it into
* the given uint64_t variable.
*
* Calling this function within a callback will not return the time since the
@@ -251,17 +292,21 @@ rcl_timer_get_time_until_next_call(const rcl_timer_t * timer, int64_t * time_unt
* The time_since_last_call argument must be a pointer to an already allocated
* uint64_t.
*
- * This function may allocate heap memory when an error occurs.
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_int_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[in] timer the handle to the timer which is being queried
* \param[out] time_since_last_call the struct in which the time is stored
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_TIMER_INVALID if the timer is invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_TIMER_INVALID` if the timer is invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -269,20 +314,26 @@ rcl_ret_t
rcl_timer_get_time_since_last_call(const rcl_timer_t * timer, uint64_t * time_since_last_call);
/// Retrieve the period of the timer.
-/* This function retrieves the period and copies it into the give variable.
+/**
+ * This function retrieves the period and copies it into the give variable.
*
* The period argument must be a pointer to an already allocated uint64_t.
*
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_int_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[in] timer the handle to the timer which is being queried
* \param[out] period the uint64_t in which the period is stored
- * \return RCL_RET_OK if the period was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_TIMER_INVALID if the timer is invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the period was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_TIMER_INVALID` if the timer is invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -290,24 +341,30 @@ rcl_ret_t
rcl_timer_get_period(const rcl_timer_t * timer, uint64_t * period);
/// Exchange the period of the timer and return the previous period.
-/* This function exchanges the period in the timer and copies the old one into
+/**
+ * This function exchanges the period in the timer and copies the old one into
* the give variable.
*
* Exchanging (changing) the period will not affect already waiting wait sets.
*
* The old_period argument must be a pointer to an already allocated uint64_t.
*
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_int_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[in] timer the handle to the timer which is being modified
* \param[out] new_period the uint64_t to exchange into the timer
* \param[out] old_period the uint64_t in which the previous period is stored
- * \return RCL_RET_OK if the period was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_TIMER_INVALID if the timer is invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the period was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_TIMER_INVALID` if the timer is invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -315,16 +372,22 @@ rcl_ret_t
rcl_timer_exchange_period(const rcl_timer_t * timer, uint64_t new_period, uint64_t * old_period);
/// Return the current timer callback.
-/* This function can fail, and therefore return NULL, if:
- * - timer is NULL
+/**
+ * This function can fail, and therefore return `NULL`, if:
+ * - timer is `NULL`
* - timer has not been initialized (the implementation is invalid)
*
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_uintptr_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[in] timer handle to the timer from the callback should be returned
- * \return function pointer to the callback, or NULL if an error occurred
+ * \return function pointer to the callback, or `NULL` if an error occurred
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -332,20 +395,26 @@ rcl_timer_callback_t
rcl_timer_get_callback(const rcl_timer_t * timer);
/// Exchange the current timer callback and return the current callback.
-/* This function can fail, and therefore return NULL, if:
- * - timer is NULL
+/**
+ * This function can fail, and therefore return `NULL`, if:
+ * - timer is `NULL`
* - timer has not been initialized (the implementation is invalid)
*
- * This function can set callback to null, in which case the callback is
+ * This function can set callback to `NULL`, in which case the callback is
* ignored when rcl_timer_call is called.
*
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_uintptr_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[inout] timer handle to the timer from the callback should be exchanged
* \param[in] new_callback the callback to be exchanged into the timer
- * \return function pointer to the old callback, or NULL if an error occurred
+ * \return function pointer to the old callback, or `NULL` if an error occurred
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -353,21 +422,27 @@ rcl_timer_callback_t
rcl_timer_exchange_callback(rcl_timer_t * timer, const rcl_timer_callback_t new_callback);
/// Cancel a timer.
-/* When a timer is canceled, rcl_timer_is_ready() will return false for that
+/**
+ * When a timer is canceled, rcl_timer_is_ready() will return false for that
* timer, and rcl_timer_call() will fail with RCL_RET_TIMER_CANCELED.
*
* A canceled timer can be reset with rcl_timer_reset(), and then used again.
* Calling this function on an already canceled timer will succeed.
*
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_bool.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[inout] timer the timer to be canceled
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_TIMER_INVALID if the timer is invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_TIMER_INVALID` if the timer is invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -375,21 +450,28 @@ rcl_ret_t
rcl_timer_cancel(rcl_timer_t * timer);
/// Retrieve the canceled state of a timer.
-/* If the timer is canceled true will be stored in the is_canceled argument.
+/**
+ * If the timer is canceled true will be stored in the is_canceled argument.
* Otherwise false will be stored in the is_canceled argument.
*
* The is_canceled argument must point to an allocated bool, as the result is
* copied into this variable.
*
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_bool.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_bool`
*
* \param[in] timer the timer to be queried
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_TIMER_INVALID if the timer is invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \param[out] is_canceled storage for the is canceled bool
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_TIMER_INVALID` if the timer is invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -397,19 +479,25 @@ rcl_ret_t
rcl_timer_is_canceled(const rcl_timer_t * timer, bool * is_canceled);
/// Reset a timer.
-/* This function can be called on a timer, canceled or not.
+/**
+ * This function can be called on a timer, canceled or not.
* For all timers it will reset the last call time to now.
* For canceled timers it will additionally make the timer not canceled.
*
- * This function is thread-safe.
- * This function is lock-free so long as the C11's stdatomic.h function
- * atomic_is_lock_free() returns true for atomic_int_least64_t.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | Yes
+ * Uses Atomics | Yes
+ * Lock-Free | Yes [1]
+ * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t`
*
* \param[inout] timer the timer to be reset
- * \return RCL_RET_OK if the last call time was retrieved successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_TIMER_INVALID if the timer is invalid, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` if the last call time was retrieved successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_TIMER_INVALID` if the timer is invalid, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/include/rcl/types.h b/rcl/include/rcl/types.h
index f4b15f1..bf6bdc4 100644
--- a/rcl/include/rcl/types.h
+++ b/rcl/include/rcl/types.h
@@ -18,35 +18,65 @@
#include
typedef rmw_ret_t rcl_ret_t;
+/// Success return code.
#define RCL_RET_OK RMW_RET_OK
+/// Unspecified error return code.
#define RCL_RET_ERROR RMW_RET_ERROR
+/// Timeout occurred return code.
#define RCL_RET_TIMEOUT RMW_RET_TIMEOUT
+
// rcl specific ret codes start at 100
+/// rcl_init() already called return code.
#define RCL_RET_ALREADY_INIT 100
+/// rcl_init() not yet called return code.
#define RCL_RET_NOT_INIT 101
+/// Failed to allocate memory return code.
#define RCL_RET_BAD_ALLOC 102
+/// Invalid argument return code.
#define RCL_RET_INVALID_ARGUMENT 103
+/// Mismatched rmw identifier return code.
#define RCL_RET_MISMATCHED_RMW_ID 104
+
// rcl node specific ret codes in 2XX
+/// Invalid rcl_node_t given return code.
#define RCL_RET_NODE_INVALID 200
+
// rcl publisher specific ret codes in 3XX
+/// Invalid rcl_publisher_t given return code.
#define RCL_RET_PUBLISHER_INVALID 300
+
// rcl subscription specific ret codes in 4XX
+/// Invalid rcl_subscription_t given return code.
#define RCL_RET_SUBSCRIPTION_INVALID 400
+/// Failed to take a message from the subscription return code.
#define RCL_RET_SUBSCRIPTION_TAKE_FAILED 401
+
// rcl service client specific ret codes in 5XX
+/// Invalid rcl_client_t given return code.
#define RCL_RET_CLIENT_INVALID 500
+/// Failed to take a response from the client return code.
#define RCL_RET_CLIENT_TAKE_FAILED 501
+
// rcl service server specific ret codes in 6XX
+/// Invalid rcl_service_t given return code.
#define RCL_RET_SERVICE_INVALID 600
+/// Failed to take a request from the service return code.
#define RCL_RET_SERVICE_TAKE_FAILED 601
+
// rcl guard condition specific ret codes in 7XX
+
// rcl timer specific ret codes in 8XX
+/// Invalid rcl_timer_t given return code.
#define RCL_RET_TIMER_INVALID 800
+/// Given timer was canceled return code.
#define RCL_RET_TIMER_CANCELED 801
+
// rcl wait and wait set specific ret codes in 9XX
+/// Invalid rcl_wait_set_t given return code.
#define RCL_RET_WAIT_SET_INVALID 900
+/// Given rcl_wait_set_t is empty return code.
#define RCL_RET_WAIT_SET_EMPTY 901
+/// Given rcl_wait_set_t is full return code.
#define RCL_RET_WAIT_SET_FULL 902
#endif // RCL__TYPES_H_
diff --git a/rcl/include/rcl/wait.h b/rcl/include/rcl/wait.h
index 323b29b..c9f3b47 100644
--- a/rcl/include/rcl/wait.h
+++ b/rcl/include/rcl/wait.h
@@ -56,19 +56,20 @@ typedef struct rcl_wait_set_t
struct rcl_wait_set_impl_t * impl;
} rcl_wait_set_t;
-/// Return a rcl_wait_set_t struct with members set to NULL.
+/// Return a rcl_wait_set_t struct with members set to `NULL`.
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_wait_set_t
rcl_get_zero_initialized_wait_set(void);
/// Initialize a rcl wait set with space for items to be waited on.
-/* This function allocates space for the subscriptions and other wait-able
+/**
+ * This function allocates space for the subscriptions and other wait-able
* entities that can be stored in the wait set.
* It also sets the allocator to the given allocator and initializes the pruned
* member to be false.
*
- * The wait_set struct should be allocated and initialized to NULL.
+ * The wait_set struct should be allocated and initialized to `NULL`.
* If the wait_set is allocated but the memory is uninitialized the behavior is
* undefined.
* Calling this function on a wait set that has already been initialized will
@@ -79,17 +80,23 @@ rcl_get_zero_initialized_wait_set(void);
*
* Expected usage:
*
- * #include
+ * ```c
+ * #include
*
- * rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
- * rcl_ret_t ret = rcl_wait_set_init(&wait_set, 42, 42, rcl_get_default_allocator());
- * // ... error handling, then use it, then call the matching fini:
- * ret = rcl_wait_set_fini(&wait_set);
- * // ... error handling
+ * rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
+ * rcl_ret_t ret = rcl_wait_set_init(&wait_set, 42, 42, rcl_get_default_allocator());
+ * // ... error handling, then use it, then call the matching fini:
+ * ret = rcl_wait_set_fini(&wait_set);
+ * // ... error handling
+ * ```
*
- * This function is thread-safe for different wait_set objects.
- * Thread-safety of this function requires a thread-safe allocator if the
- * allocator is shared with other parts of the system.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] wait_set the wait set struct to be initialized
* \param[in] number_of_subscriptions non-zero size of the subscriptions set
@@ -98,11 +105,11 @@ rcl_get_zero_initialized_wait_set(void);
* \param[in] number_of_clients non-zero size of the clients set
* \param[in] number_of_services non-zero size of the services set
* \param[in] allocator the allocator to use when allocating space in the sets
- * \return RCL_RET_OK if the wait set is initialized successfully, or
- * RCL_RET_ALREADY_INIT if the wait set is not zero initialized, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the wait set is initialized successfully, or
+ * \return `RCL_RET_ALREADY_INIT` if the wait set is not zero initialized, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -117,7 +124,8 @@ rcl_wait_set_init(
rcl_allocator_t allocator);
/// Finalize a rcl wait set.
-/* Deallocates any memory in the wait set that was allocated in
+/**
+ * Deallocates any memory in the wait set that was allocated in
* rcl_wait_set_init() using the allocator given in the initialization.
*
* Calling this function on a zero initialized wait set will do nothing and
@@ -127,13 +135,18 @@ rcl_wait_set_init(
* and so calling this function or rcl_wait_set_init() immediately after will
* succeed.
*
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] wait_set the wait set struct to be finalized.
- * \return RCL_RET_OK if the finalization was successful, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the finalization was successful, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -141,17 +154,23 @@ rcl_ret_t
rcl_wait_set_fini(rcl_wait_set_t * wait_set);
/// Retrieve the wait set's allocator.
-/* The allocator must be an allocated rcl_allocator_t struct, as the result is
+/**
+ * The allocator must be an allocated rcl_allocator_t struct, as the result is
* copied into this variable.
*
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[in] wait_set the handle to the wait set
* \param[out] allocator the rcl_allocator_t struct to which the result is copied
- * \return RCL_RET_OK if the allocator was successfully retrieved, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if the allocator was successfully retrieved, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -159,22 +178,28 @@ rcl_ret_t
rcl_wait_set_get_allocator(const rcl_wait_set_t * wait_set, rcl_allocator_t * allocator);
/// Store a pointer to the given subscription in the next empty spot in the set.
-/* This function does not guarantee that the subscription is not already in the
+/**
+ * This function does not guarantee that the subscription is not already in the
* wait set.
*
* Also add the rmw representation to the underlying rmw array and increment
* the rmw array count.
*
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] wait_set struct in which the subscription is to be stored
* \param[in] subscription the subscription to be added to the wait set
- * \return RCL_RET_OK if added successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_WAIT_SET_INVALID if the wait set is zero initialized, or
- * RCL_RET_WAIT_SET_FULL if the subscription set is full, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if added successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_WAIT_SET_INVALID` if the wait set is zero initialized, or
+ * \return `RCL_RET_WAIT_SET_FULL` if the subscription set is full, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -183,22 +208,28 @@ rcl_wait_set_add_subscription(
rcl_wait_set_t * wait_set,
const rcl_subscription_t * subscription);
-/// Remove (sets to NULL) the subscriptions in the wait set.
-/* This function should be used after passing using rcl_wait, but before
+/// Remove (sets to `NULL`) the subscriptions in the wait set.
+/**
+ * This function should be used after passing using rcl_wait, but before
* adding new subscriptions to the set.
- * Sets all of the entries in the underlying rmw array to null, and sets the
- * count in the rmw array to 0.
+ * Sets all of the entries in the underlying rmw array to `NULL`, and sets the
+ * count in the rmw array to `0`.
*
* Calling this on an uninitialized (zero initialized) wait set will fail.
*
- * This function is not thread-safe.
- * This function is lock-free.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | No
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] wait_set struct to have its subscriptions cleared
- * \return RCL_RET_OK if cleared successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_WAIT_SET_INVALID if the wait set is zero initialized, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if cleared successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_WAIT_SET_INVALID` if the wait set is zero initialized, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -206,31 +237,38 @@ rcl_ret_t
rcl_wait_set_clear_subscriptions(rcl_wait_set_t * wait_set);
/// Reallocate space for the subscriptions in the wait set.
-/* This function will deallocate and reallocate the memory for the
+/**
+ * This function will deallocate and reallocate the memory for the
* subscriptions set.
*
- * A size of 0 will just deallocate the memory and assign NULL to the array.
+ * A size of 0 will just deallocate the memory and assign `NULL` to the array.
*
* Allocation and deallocation is done with the allocator given during the
* wait set's initialization.
*
- * After calling this function all values in the set will be set to NULL,
+ * After calling this function all values in the set will be set to `NULL`,
* effectively the same as calling rcl_wait_set_clear_subscriptions().
* Similarly, the underlying rmw representation is reallocated and reset:
- * all entries are set to null and the count is set to zero.
+ * all entries are set to `NULL` and the count is set to zero.
*
* If the requested size matches the current size, no allocation will be done.
*
* This can be called on an uninitialized (zero initialized) wait set.
*
- * This function is not thread-safe.
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
*
* \param[inout] wait_set struct to have its subscriptions cleared
* \param[in] size a size for the new set
- * \return RCL_RET_OK if resized successfully, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_BAD_ALLOC if allocating memory failed, or
- * RCL_RET_ERROR if an unspecified error occurs.
+ * \return `RCL_RET_OK` if resized successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
@@ -238,7 +276,8 @@ rcl_ret_t
rcl_wait_set_resize_subscriptions(rcl_wait_set_t * wait_set, size_t size);
/// Store a pointer to the guard condition in the next empty spot in the set.
-/* This function behaves exactly the same as for subscriptions.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_add_subscription
*/
RCL_PUBLIC
@@ -248,8 +287,9 @@ rcl_wait_set_add_guard_condition(
rcl_wait_set_t * wait_set,
const rcl_guard_condition_t * guard_condition);
-/// Remove (sets to NULL) the guard conditions in the wait set.
-/* This function behaves exactly the same as for subscriptions.
+/// Remove (sets to `NULL`) the guard conditions in the wait set.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_clear_subscriptions
*/
RCL_PUBLIC
@@ -258,7 +298,8 @@ rcl_ret_t
rcl_wait_set_clear_guard_conditions(rcl_wait_set_t * wait_set);
/// Reallocate space for the guard conditions in the wait set.
-/* This function behaves exactly the same as for subscriptions.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_resize_subscriptions
*/
RCL_PUBLIC
@@ -267,7 +308,8 @@ rcl_ret_t
rcl_wait_set_resize_guard_conditions(rcl_wait_set_t * wait_set, size_t size);
/// Store a pointer to the timer in the next empty spot in the set.
-/* This function behaves exactly the same as for subscriptions.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_add_subscription
*/
RCL_PUBLIC
@@ -277,8 +319,9 @@ rcl_wait_set_add_timer(
rcl_wait_set_t * wait_set,
const rcl_timer_t * timer);
-/// Remove (sets to NULL) the timers in the wait set.
-/* This function behaves exactly the same as for subscriptions.
+/// Remove (sets to `NULL`) the timers in the wait set.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_clear_subscriptions
*/
RCL_PUBLIC
@@ -287,7 +330,8 @@ rcl_ret_t
rcl_wait_set_clear_timers(rcl_wait_set_t * wait_set);
/// Reallocate space for the timers in the wait set.
-/* This function behaves exactly the same as for subscriptions.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_resize_subscriptions
*/
RCL_PUBLIC
@@ -296,7 +340,8 @@ rcl_ret_t
rcl_wait_set_resize_timers(rcl_wait_set_t * wait_set, size_t size);
/// Store a pointer to the client in the next empty spot in the set.
-/* This function behaves exactly the same as for subscriptions.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_add_subscription
*/
RCL_PUBLIC
@@ -306,8 +351,9 @@ rcl_wait_set_add_client(
rcl_wait_set_t * wait_set,
const rcl_client_t * client);
-/// Remove (sets to NULL) the clients in the wait set.
-/* This function behaves exactly the same as for subscriptions.
+/// Remove (sets to `NULL`) the clients in the wait set.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_clear_subscriptions
*/
RCL_PUBLIC
@@ -316,7 +362,8 @@ rcl_ret_t
rcl_wait_set_clear_clients(rcl_wait_set_t * wait_set);
/// Reallocate space for the clients in the wait set.
-/* This function behaves exactly the same as for subscriptions.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_resize_subscriptions
*/
RCL_PUBLIC
@@ -325,7 +372,8 @@ rcl_ret_t
rcl_wait_set_resize_clients(rcl_wait_set_t * wait_set, size_t size);
/// Store a pointer to the client in the next empty spot in the set.
-/* This function behaves exactly the same as for subscriptions.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_add_subscription
*/
RCL_PUBLIC
@@ -335,8 +383,9 @@ rcl_wait_set_add_service(
rcl_wait_set_t * wait_set,
const rcl_service_t * service);
-/// Remove (sets to NULL) the services in the wait set.
-/* This function behaves exactly the same as for subscriptions.
+/// Remove (sets to `NULL`) the services in the wait set.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_clear_subscriptions
*/
RCL_PUBLIC
@@ -345,7 +394,8 @@ rcl_ret_t
rcl_wait_set_clear_services(rcl_wait_set_t * wait_set);
/// Reallocate space for the services in the wait set.
-/* This function behaves exactly the same as for subscriptions.
+/**
+ * This function behaves exactly the same as for subscriptions.
* \see rcl_wait_set_resize_subscriptions
*/
RCL_PUBLIC
@@ -354,66 +404,69 @@ rcl_ret_t
rcl_wait_set_resize_services(rcl_wait_set_t * wait_set, size_t size);
/// Block until the wait set is ready or until the timeout has been exceeded.
-/* This function will collect the items in the rcl_wait_set_t and pass them
+/**
+ * This function will collect the items in the rcl_wait_set_t and pass them
* to the underlying rmw_wait function.
*
- * The items in the wait set will be either left untouched or set to NULL after
+ * The items in the wait set will be either left untouched or set to `NULL` after
* this function returns.
- * Items that are not NULL are ready, where ready means different things based
+ * Items that are not `NULL` are ready, where ready means different things based
* on the type of the item.
* For subscriptions this means there are messages that can be taken.
* For guard conditions this means the guard condition was triggered.
*
* Expected usage:
*
- * #include
+ * ```c
+ * #include
*
- * // rcl_init() called successfully before here...
- * rcl_node_t node; // initialize this, see rcl_node_init()
- * rcl_subscription_t sub1; // initialize this, see rcl_subscription_init()
- * rcl_subscription_t sub2; // initialize this, see rcl_subscription_init()
- * rcl_guard_condition_t gc1; // initialize this, see rcl_guard_condition_init()
- * rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
- * rcl_ret_t ret = rcl_wait_set_init(&wait_set, 2, 1, 0, rcl_get_default_allocator());
+ * // rcl_init() called successfully before here...
+ * rcl_node_t node; // initialize this, see rcl_node_init()
+ * rcl_subscription_t sub1; // initialize this, see rcl_subscription_init()
+ * rcl_subscription_t sub2; // initialize this, see rcl_subscription_init()
+ * rcl_guard_condition_t gc1; // initialize this, see rcl_guard_condition_init()
+ * rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
+ * rcl_ret_t ret = rcl_wait_set_init(&wait_set, 2, 1, 0, rcl_get_default_allocator());
+ * // ... error handling
+ * do {
+ * ret = rcl_wait_set_clear_subscriptions(&wait_set);
* // ... error handling
- * do {
- * ret = rcl_wait_set_clear_subscriptions(&wait_set);
- * // ... error handling
- * ret = rcl_wait_set_clear_guard_conditions(&wait_set);
- * // ... error handling
- * ret = rcl_wait_set_add_subscription(&wait_set, &sub1);
- * // ... error handling
- * ret = rcl_wait_set_add_subscription(&wait_set, &sub2);
- * // ... error handling
- * ret = rcl_wait_set_add_guard_condition(&wait_set, &gc1);
- * // ... error handling
- * ret = rcl_wait(&wait_set, RCL_MS_TO_NS(1000)); // 1000ms == 1s, passed as ns
- * if (ret == RCL_RET_TIMEOUT) {
- * continue;
- * }
- * for (int i = 0; i < wait_set.size_of_subscriptions; ++i) {
- * if (wait_set.subscriptions[i]) {
- * // The subscription is ready...
- * }
- * }
- * for (int i = 0; i < wait_set.size_of_guard_conditions; ++i) {
- * if (wait_set.guard_conditions[i]) {
- * // The subscription is ready...
- * }
- * }
- * } while(check_some_condition());
- * // ... fini node, and subscriptions and guard conditions...
- * ret = rcl_wait_set_fini(&wait_set);
+ * ret = rcl_wait_set_clear_guard_conditions(&wait_set);
* // ... error handling
+ * ret = rcl_wait_set_add_subscription(&wait_set, &sub1);
+ * // ... error handling
+ * ret = rcl_wait_set_add_subscription(&wait_set, &sub2);
+ * // ... error handling
+ * ret = rcl_wait_set_add_guard_condition(&wait_set, &gc1);
+ * // ... error handling
+ * ret = rcl_wait(&wait_set, RCL_MS_TO_NS(1000)); // 1000ms == 1s, passed as ns
+ * if (ret == RCL_RET_TIMEOUT) {
+ * continue;
+ * }
+ * for (int i = 0; i < wait_set.size_of_subscriptions; ++i) {
+ * if (wait_set.subscriptions[i]) {
+ * // The subscription is ready...
+ * }
+ * }
+ * for (int i = 0; i < wait_set.size_of_guard_conditions; ++i) {
+ * if (wait_set.guard_conditions[i]) {
+ * // The subscription is ready...
+ * }
+ * }
+ * } while(check_some_condition());
+ * // ... fini node, and subscriptions and guard conditions...
+ * ret = rcl_wait_set_fini(&wait_set);
+ * // ... error handling
+ * ```
*
* The wait set struct must be allocated, initialized, and should have been
* cleared and then filled with items, e.g. subscriptions and guard conditions.
* Passing a wait set with no wait-able items in it will fail.
- * NULL items in the sets are ignored, e.g. it is valid to have as input:
- * - subscriptions[0] = valid pointer
- * - subscriptions[1] = NULL
- * - subscriptions[2] = valid pointer
- * - size_of_subscriptions = 3
+ * `NULL` items in the sets are ignored, e.g. it is valid to have as input:
+ * - `subscriptions[0]` = valid pointer
+ * - `subscriptions[1]` = `NULL`
+ * - `subscriptions[2]` = valid pointer
+ * - `size_of_subscriptions` = 3
* Passing an uninitialized (zero initialized) wait set struct will fail.
* Passing a wait set struct with uninitialized memory is undefined behavior.
*
@@ -430,17 +483,17 @@ rcl_wait_set_resize_services(rcl_wait_set_t * wait_set, size_t size);
* This function is thread-safe for unique wait sets with unique contents.
* This function cannot operate on the same wait set in multiple threads, and
* the wait sets may not share content.
- * For example, calling rcl_wait in two threads on two different wait sets that
- * both contain a single, shared guard condition is undefined behavior.
+ * For example, calling rcl_wait() in two threads on two different wait sets
+ * that both contain a single, shared guard condition is undefined behavior.
*
* \param[inout] wait_set the set of things to be waited on and to be pruned if not ready
* \param[in] timeout the duration to wait for the wait set to be ready, in nanoseconds
- * \return RCL_RET_OK something in the wait set became ready, or
- * RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or
- * RCL_RET_WAIT_SET_INVALID if the wait set is zero initialized, or
- * RCL_RET_WAIT_SET_EMPTY if the wait set contains no items, or
- * RCL_RET_TIMEOUT if the timeout expired before something was ready, or
- * RCL_RET_ERROR an unspecified error occur.
+ * \return `RCL_RET_OK` something in the wait set became ready, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
+ * \return `RCL_RET_WAIT_SET_INVALID` if the wait set is zero initialized, or
+ * \return `RCL_RET_WAIT_SET_EMPTY` if the wait set contains no items, or
+ * \return `RCL_RET_TIMEOUT` if the timeout expired before something was ready, or
+ * \return `RCL_RET_ERROR` an unspecified error occur.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
diff --git a/rcl/src/rcl/client.c b/rcl/src/rcl/client.c
index b66fd36..a982d4e 100644
--- a/rcl/src/rcl/client.c
+++ b/rcl/src/rcl/client.c
@@ -117,6 +117,7 @@ rcl_client_fini(rcl_client_t * client, rcl_node_t * node)
rcl_client_options_t
rcl_client_get_default_options()
{
+ // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING
static rcl_client_options_t default_options;
// Must set the allocator and qos after because they are not a compile time constant.
default_options.qos = rmw_qos_profile_services_default;
diff --git a/rcl/src/rcl/guard_condition.c b/rcl/src/rcl/guard_condition.c
index 373c9e1..de9f0cd 100644
--- a/rcl/src/rcl/guard_condition.c
+++ b/rcl/src/rcl/guard_condition.c
@@ -127,6 +127,7 @@ rcl_guard_condition_fini(rcl_guard_condition_t * guard_condition)
rcl_guard_condition_options_t
rcl_guard_condition_get_default_options()
{
+ // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING
static rcl_guard_condition_options_t default_options;
default_options.allocator = rcl_get_default_allocator();
return default_options;
diff --git a/rcl/src/rcl/node.c b/rcl/src/rcl/node.c
index 76327ed..e987f0c 100644
--- a/rcl/src/rcl/node.c
+++ b/rcl/src/rcl/node.c
@@ -197,6 +197,7 @@ rcl_node_is_valid(const rcl_node_t * node)
rcl_node_options_t
rcl_node_get_default_options()
{
+ // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING
static rcl_node_options_t default_options = {
.domain_id = RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID,
};
diff --git a/rcl/src/rcl/publisher.c b/rcl/src/rcl/publisher.c
index be8184c..6959623 100644
--- a/rcl/src/rcl/publisher.c
+++ b/rcl/src/rcl/publisher.c
@@ -113,6 +113,7 @@ rcl_publisher_fini(rcl_publisher_t * publisher, rcl_node_t * node)
rcl_publisher_options_t
rcl_publisher_get_default_options()
{
+ // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING
static rcl_publisher_options_t default_options;
// Must set the allocator and qos after because they are not a compile time constant.
default_options.qos = rmw_qos_profile_default;
diff --git a/rcl/src/rcl/service.c b/rcl/src/rcl/service.c
index d7d207b..c1fd2ad 100644
--- a/rcl/src/rcl/service.c
+++ b/rcl/src/rcl/service.c
@@ -119,6 +119,7 @@ rcl_service_fini(rcl_service_t * service, rcl_node_t * node)
rcl_service_options_t
rcl_service_get_default_options()
{
+ // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING
static rcl_service_options_t default_options;
// Must set the allocator and qos after because they are not a compile time constant.
default_options.qos = rmw_qos_profile_services_default;
diff --git a/rcl/src/rcl/subscription.c b/rcl/src/rcl/subscription.c
index 18df1cc..d394afd 100644
--- a/rcl/src/rcl/subscription.c
+++ b/rcl/src/rcl/subscription.c
@@ -108,6 +108,7 @@ rcl_subscription_fini(rcl_subscription_t * subscription, rcl_node_t * node)
rcl_subscription_options_t
rcl_subscription_get_default_options()
{
+ // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING
static rcl_subscription_options_t default_options = {
.ignore_local_publications = false,
};