Function rmw_take_sequence

Function Documentation

rmw_ret_t rmw_take_sequence(const rmw_subscription_t *subscription, size_t count, rmw_message_sequence_t *message_sequence, rmw_message_info_sequence_t *message_info_sequence, size_t *taken, rmw_subscription_allocation_t *allocation)

Take multiple incoming ROS messages with their metadata.

Take a sequence of consecutive ROS messages already received by the given subscription, removing them from internal queues. While count ROS messages may be requested, fewer messages may have been received by the subscription. This function will only take what has been already received, and it will succeed even if fewer (or zero) messages were received. In this case, only currently available messages will be returned. The taken output variable indicates the number of ROS messages actually taken.

Attribute

Adherence

Allocates Memory

Maybe

Thread-Safe

Yes

Uses Atomics

Maybe [1]

Lock-Free

Maybe [1]

Remark

Once taken, ROS messages in the sequence cannot be taken again. Callers do not have to deal with duplicates.

[1] implementation defined, check implementation documentation.

Runtime behavior

To take a sequence of ROS messages is a synchronous operation. It is also non-blocking, to the extent it will not wait for new ROS messages to arrive, 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 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. Moreover, the sequence of ROS messages taken is guaranteed to be consecutive and to preserve the order in the subscription queues, despite any concurrent takes. However, when taking a sequence of ROS messages with metadata:

  • Access to the given ROS message sequence is not synchronized. It is not safe to read or write message_sequence while rmw_take_sequence() uses it.

  • Access to the given ROS message metadata sequence is not synchronized. It is not safe to read or write message_info_sequence while rmw_take_sequence() uses it.

  • Access to given primitive data-type arguments is not synchronized. It is not safe to read or write taken while rmw_take_sequence() uses it.

  • 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_sequence() uses it. Check the implementation documentation to learn about subscription allocations’ thread-safety.

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

  • count[in] Number of messages to attempt to take.

  • message_sequence[out] Sequence of type erase ROS messages to write to. Message sequence capacity has to be enough to hold all requested messages i.e. capacity has to be equal or greater than count. It does not have to match that of message_info_sequence.

  • message_info_sequence[out] Sequence of additional message metadata. Message info sequence capacity has to be enough to hold all requested messages metadata i.e. capacity has to be equal or greater than count. It does not have to match that of message_sequence.

  • taken[out] Number of messages actually taken from subscription.

  • 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:

Given message_sequence must be a valid message sequence, initialized by rmw_message_sequence_init() and populated with ROS messages whose type matches the message type support registered with the subscription on creation.

Pre:

Given message_info_sequence must be a valid message metadata sequence, initialized by rmw_message_info_sequence_init().

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 message_sequence will remain a valid message sequence, and message_info_sequence, a valid message metadata sequence. Both will be left unchanged if this function fails early due to a logical error, such as an invalid argument, or in an unknown yet valid state if it fails due to a runtime error. Both will also be left unchanged if this function succeeds but taken is zero.

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 message_sequence is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if message_info_sequence is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if taken is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if count is 0, or

Returns:

RMW_RET_INVALID_ARGUMENT if message_sequence capacity is less than count, or

Returns:

RMW_RET_INVALID_ARGUMENT if message_info_sequence capacity is less than count, or

Returns:

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

Returns:

RMW_RET_ERROR if an unexpected error occurs.