Function rmw_take_request

Function Documentation

rmw_ret_t rmw_take_request(const rmw_service_t *service, rmw_service_info_t *request_header, void *ros_request, bool *taken)

Take an incoming ROS service request.

Take a ROS service request already received by the given service server, removing it from internal queues. The request 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, for each remote service client, a ROS service request with its corresponding ROS service response, to be later sent using rmw_send_response().

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 request cannot be taken twice. Callers do not have to deal with duplicates.

[1] implementation defined, check implementation documentation.

Runtime behavior

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

Thread-safety

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

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

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

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

Parameters:
  • service[in] Service server to take request from.

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

  • ros_request[out] Type erased ROS service request to write to.

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

Pre:

Given service must be a valid service, as returned by rmw_create_service().

Pre:

Given ros_request must be a valid service request, whose type matches the service type support registered with the service on creation.

Post:

Given ros_request will remain a valid service request. 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 service is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if request_header is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if ros_request is NULL, or

Returns:

RMW_RET_INVALID_ARGUMENT if taken is NULL, or

Returns:

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

Returns:

RMW_RET_ERROR if an unexpected error occurs.