Function rmw_take_loaned_message

Function Documentation

rmw_ret_t rmw_take_loaned_message(const rmw_subscription_t *subscription, void **loaned_message, bool *taken, rmw_subscription_allocation_t *allocation)

Take an incoming ROS message, loaned by the middleware.

Take a ROS message already received by the given subscription, removing it from internal queues. This function will succeed even if no ROS message was received, but taken will be false. The loaned ROS message is owned by the middleware, which will keep it alive (i.e. in valid memory space) until the caller returns it using rmw_return_loaned_message_from_subscription().

Attribute

Adherence

Allocates Memory

Maybe

Thread-Safe

Yes

Uses Atomics

Maybe [1]

Lock-Free

Maybe [1]

Remark

The same ROS message, loaned or not, cannot be taken twice. Callers do not have to deal with duplicates.

[1] implementation defined, check implementation documentation.

Runtime behavior

To take a loaned ROS message is a synchronous operation. It is also non-blocking, to the extent it will not wait for new ROS messages to arrive nor for internal memory loaning pools, if any, to be replenished, but it is not guaranteed to be lock-free. Generally speaking, implementations may synchronize access to internal resources using locks but are not allowed to wait for events with no guaranteed time bound (barring the effects of starvation due to OS scheduling).

Memory allocation

It is implementation defined whether memory will be allocated on take or not. For instance, implementations that deserialize ROS messages received over the wire may need to perform additional memory allocations when dealing with unbounded (dynamically-sized) fields. A subscription allocation, if provided, may or may not be used. Check the implementation documentation to learn about memory allocation guarantees when taking loaned ROS messages with and without subscription allocations.

Thread-safety

Subscriptions are thread-safe objects, and so are all operations on them except for finalization. Therefore, it is safe to take from the same subscription concurrently. However, when taking loaned ROS messages:

  • Access to given primitive data-type arguments is not synchronized. It is not safe to read or write taken nor loaned_message while rmw_take_loaned_message() uses them.

  • Access to the given subscription allocation is not synchronized, unless specifically stated otherwise by the implementation. Thus, it is generally not safe to read or write allocation while rmw_take_loaned_message() uses it. Check the implementation documentation to learn about subscription allocations’ thread-safety.

Parameters:
  • subscription[in] Subscription to take ROS message from.

  • loaned_message[inout] Pointer to type erased ROS message taken and loaned by the middleware.

  • taken[out] Boolean flag indicating if a ROS message was taken or not.

  • allocation[in] Pre-allocated memory to use. May be NULL.

Pre:

Given subscription must be a valid subscription, as returned by rmw_create_subscription().

Pre:

If not NULL, given allocation must be a valid subscription allocation initialized with rmw_subscription_allocation_init() with a message type support that matches the one registered with subscription on creation.

Post:

Given loaned_message will remain unchanged, or point to a valid message if this function was successful and taken is true.

Returns:

RMW_RET_OK if successful, or

Returns:

RMW_RET_BAD_ALLOC if memory allocation fails, or

Returns:

RMW_RET_INVALID_ARGUMENT if subscription is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if loaned_message is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if *loaned_message is not NULL (to prevent leaks), or

Returns:

RMW_RET_INVALID_ARGUMENT if taken is NULL, or

Returns:

RMW_RET_INCORRECT_RMW_IMPLEMENTATION if the subscription implementation identifier does not match this implementation, or

Returns:

RMW_RET_UNSUPPORTED if the implementation does not support loaned ROS messages, or

Returns:

RMW_RET_ERROR if an unexpected error occurs.