Function rcl_wait

Function Documentation

rcl_ret_t rcl_wait(rcl_wait_set_t *wait_set, int64_t timeout)

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 to the underlying rmw_wait function.

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 on the type of the item. For subscriptions this means there may be messages that can be taken, or perhaps that the state of the subscriptions has changed, in which case rcl_take may succeed but return with taken == false. For guard conditions this means the guard condition was triggered.

Expected usage:

#include <rcl/rcl.h>

// 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, 0, 0, rcl_get_default_allocator());
// ... error handling
do {
  ret = rcl_wait_set_clear(&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 Passing an uninitialized (zero initialized) wait set struct will fail. Passing a wait set struct with uninitialized memory is undefined behavior.

The unit of timeout is nanoseconds. If the timeout is negative then this function will block indefinitely until something in the wait set is valid or it is interrupted. If the timeout is 0 then this function will be non-blocking; checking what’s ready now, but not waiting if nothing is ready yet. If the timeout is greater than 0 then this function will return after that period of time has elapsed or the wait set becomes ready, which ever comes first. Passing a timeout struct with uninitialized memory is undefined behavior.

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.

Parameters:
  • wait_set[inout] the set of things to be waited on and to be pruned if not ready

  • timeout[in] the duration to wait for the wait set to be ready, in nanoseconds

Returns:

RCL_RET_OK something in the wait set became ready, or

Returns:

RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or

Returns:

RCL_RET_WAIT_SET_INVALID if the wait set is zero initialized, or

Returns:

RCL_RET_WAIT_SET_EMPTY if the wait set contains no items, or

Returns:

RCL_RET_TIMEOUT if the timeout expired before something was ready, or

Returns:

RCL_RET_ERROR an unspecified error occur.