Function rmw_take_response

Function Documentation

rmw_ret_t rmw_take_response(const rmw_client_t *client, rmw_service_info_t *request_header, void *ros_response, bool *taken)

Take an incoming ROS service response.

Take a ROS service response already received by the given service server, removing it from internal queues. The response header (i.e. its metadata), containing at least the writer guid and sequence number, is also retrieved. Both writer guid and sequence number allow callers to pair, potentially for each remote service server, a ROS service response with its corresponding ROS service request, previously sent using rmw_send_request().

This function will succeed even if no ROS service request was received, but taken will be false.

Attribute

Adherence

Allocates Memory

Maybe

Thread-Safe

Yes

Uses Atomics

Maybe [1]

Lock-Free

Maybe [1]

Remark

The same ROS service response cannot be taken twice. Callers do not have to deal with duplicates.

[1] implementation defined, check implementation documentation.

Runtime behavior

Taking a ROS service response is a synchronous operation. It is also non-blocking, to the extent it will not wait for new ROS service responses 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 service responses received over the wire may need to perform additional memory allocations when dealing with unbounded (dynamically-sized) fields.

Thread-safety

Service clients are thread-safe objects, and so are all operations on them except for finalization. Therefore, it is safe to take responses from the same service client concurrently. However:

  • Access to the given ROS service response is not synchronized. It is not safe to read or write ros_response while rmw_take_request() uses it.

  • Access to the given ROS service response header is not synchronized. It is not safe to read or write request_header while rmw_take_response() uses it.

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

Note

It is implementation defined how many responses a given request may get, considering there may be more than one server for the same service in the ROS graph.

Parameters:
  • client[in] Service client to take response from.

  • request_header[out] Service response header to write to.

  • ros_response[out] Type erased ROS service response to write to.

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

Pre:

Given client must be a valid client, as returned by rmw_create_client().

Pre:

Given ros_response must be a valid service response, whose type matches the service type support registered with the client on creation.

Post:

Given ros_response will remain a valid service response. It 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. It will also be left unchanged if this function succeeds but taken is false.

Returns:

RMW_RET_OK if successful, or

Returns:

RMW_RET_BAD_ALLOC if memory allocation fails, or

Returns:

RMW_RET_INVALID_ARGUMENT if client is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if request_header is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if ros_response is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if taken is NULL, or

Returns:

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

Returns:

RMW_RET_ERROR if an unexpected error occurs.