-
Notifications
You must be signed in to change notification settings - Fork 178
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Feature request
This is a request for an API on top of the current waitset api that considers groups of waitable entities.
Feature description
An API that covers groups of entities that can be waited on would be immediately useful for actions. A server and client consists of several waitable entities (servers, clients, maybe a timer). The API would allow a client library to add a group of waitable entities to the wait set, and then notify the action server when one of them becomes available.
Implementation considerations
This could be implemented in a package rcl_grouped_waitset
on top of the existing rcl
API
Structs and methods to be added.
struct rcl_grouped_waitset
{
rcl_waitset_group_t * groups;
size_t num_groups;
rcl_waitset_group_impl_t * impl;
}
struct rcl_waitset_group_t
{
rcl_subscription_t * subscriptions;
rcl_guard_condition_t * guard_conditions;
rcl_timer_t * timers;
rcl_client_t * clients;
rcl_service_t * servers;
size_t num_subscriptions;
size_t num_guard_conditions;
size_t num_timers;
size_t num_clients;
size_t num_servers;
}
rcl_waitset_group_get_zero_initialized();
// User won't call these, but rcl_grouped_waitset_add and rcl_grouped_waitset_fini might
// rcl_waitset_group_init(rcl_waitset_group_t *, num_subs, subs, ..., rcl_allocator_t alloc);
// rcl_waitset_group_fini(rcl_waitset_group_t * g);
rcl_grouped_waitset_get_zero_initialized();
rcl_grouped_waitset_init(rcl_grouped_waitset_t * gws, size_t num_groups, rcl_allocator_t alloc);
rcl_grouped_waitset_fini(rcl_grouped_waitset_t * gws);
// Add a group waitable entities to the wait set
// This returns a waitset group that can be used to tell which entities in the group woke the wait set
// The returned group isn't usable until `rcl_grouped_waitset_build()` is called. The returned group never needs to be cleaned up by the user.
// subs, gcs, timers, etc pointers are borrowed and must be valid until `rcl_grouped_waitset_build()` is called
rcl_grouped_waitset_add(rcl_grouped_waitset_t * gws, rcl_waitset_group_t * g, size_t num_subs, rcl_subscription_t * subs, size_t num_guard_conditions, , rcl_guard_condition_t * gcs, size_t num_timers, rcl_timer_t * timers, size_t num_clients, rcl_client_t * clients, size_t num_servers, rcl_server_t * servers);
// Called after all groups have been added so allocation of the wait set only happens once
rcl_grouped_waitset_build();
// Calls `rcl_wait(rcl_waitset_t ws,...)` internally using a waitset built in `_build()` and stored in the implementation of the group object.
rcl_grouped_wait(rcl_grouped_waitset_t * gws, int64_t timeout);
Example use
rcl_waitset_group_t gws = rcl_grouped_waitset_get_zero_initialized();
rcl_grouped_waitset_init(&gws, num_groups, alloc);
// Client library builds a group with all of the users subs, clients, services, timers, etc
rcl_waitset_group_t cl_group = rcl_waitset_group_get_zero_initialized();
rcl_grouped_waitset_add(&gws, &cl_group, ...);
// For each action server client library asks it to add itself to the waitset group
{
rcl_waitset_group group = rcl_waitset_group_get_zero_initialized();
// This calls rcl_grouped_waitset_add() internally
rcl_action_server_add_to_grouped_waitset(&as, &gws, &group);
}
rcl_grouped_wait(gws, ...)
// Entities are set to NULL within the added groups
for (size_t g = 0; g < gws.num_groups; ++g)
{
const rcl_waitset_group_t * group = gws.groups[g];
for (size_t s = 0; s < group->num_subscriptions; ++s)
{
// client library does right thing
// First group could be user defined stuff,
// Following groups could be for action servers, action clients, etc
}
}
// When done finalizing the grouped waitset also cleans up the groups
// This works because rcl_grouped_waitset_build() set the pointers to the entities to be internal to an `rcl_waitset_t1
rcl_grouped_waitset_fini(gws);
connects to #307
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request