Skip to content

Commit dd86a13

Browse files
committed
Executor optimizations
~5% less overhead in wait_for_ready_callbacks()
1 parent 149ad43 commit dd86a13

File tree

1 file changed

+29
-20
lines changed

1 file changed

+29
-20
lines changed

rclpy/rclpy/executors.py

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ def __init__(self):
8282
gc, gc_handle = _rclpy.rclpy_create_guard_condition()
8383
self._guard_condition = gc
8484
self._guard_condition_handle = gc_handle
85+
# Triggered by signal handler for sigint
86+
(sigint_gc, sigint_gc_handle) = _rclpy.rclpy_get_sigint_guard_condition()
87+
self._sigint_gc = sigint_gc
88+
self._sigint_gc_handle = sigint_gc_handle
8589
# True if shutdown has been called
8690
self._is_shutdown = False
8791
self._work_tracker = _WorkTracker()
@@ -238,15 +242,15 @@ def handler():
238242
_rclpy.rclpy_trigger_guard_condition(gc)
239243
return handler
240244

241-
def _filter_eligible_entities(self, entities):
245+
def _can_execute(self, entity):
242246
"""
243-
Filter entities that should not be put onto the wait list.
247+
Return true if an entity is eligible for execution.
244248
245-
:param entity_list: Entities to be checked for eligibility
246-
:type entity_list: list
247-
:rtype: list
249+
:param entity: an entity to be checked
250+
:type entity_list: Client, Service, Publisher, Subscriber
251+
:rtype: bool
248252
"""
249-
return [e for e in entities if e.callback_group.can_execute(e) and not e._executor_event]
253+
return entity.callback_group.can_execute(entity) and not entity._executor_event
250254

251255
def wait_for_ready_callbacks(self, timeout_sec=None, nodes=None):
252256
"""
@@ -275,17 +279,23 @@ def wait_for_ready_callbacks(self, timeout_sec=None, nodes=None):
275279
clients = []
276280
services = []
277281
for node in nodes:
278-
subscriptions.extend(self._filter_eligible_entities(node.subscriptions))
279-
timers.extend(self._filter_eligible_entities(node.timers))
280-
clients.extend(self._filter_eligible_entities(node.clients))
281-
services.extend(self._filter_eligible_entities(node.services))
282-
node_guards = self._filter_eligible_entities(node.guards)
283-
# retrigger a guard condition that was triggered but not handled
284-
for gc in node_guards:
285-
if gc._executor_triggered:
286-
gc.trigger()
287-
guards.extend(node_guards)
288-
(sigint_gc, sigint_gc_handle) = _rclpy.rclpy_get_sigint_guard_condition()
282+
subscriptions.extend(node.subscriptions)
283+
timers.extend(node.timers)
284+
clients.extend(node.clients)
285+
services.extend(node.services)
286+
guards.extend(node.guards)
287+
288+
subscriptions = [e for e in filter(self._can_execute, subscriptions)]
289+
guards = [e for e in filter(self._can_execute, guards)]
290+
timers = [e for e in filter(self._can_execute, timers)]
291+
clients = [e for e in filter(self._can_execute, clients)]
292+
services = [e for e in filter(self._can_execute, services)]
293+
294+
# retrigger a guard condition that was triggered but not handled
295+
for gc in guards:
296+
if gc._executor_triggered:
297+
gc.trigger()
298+
289299
if timeout_timer is not None:
290300
timers.append(timeout_timer)
291301

@@ -296,16 +306,15 @@ def wait_for_ready_callbacks(self, timeout_sec=None, nodes=None):
296306
wait_set.add_services(services)
297307
wait_set.add_timers(timers)
298308
wait_set.add_guard_conditions(guards)
299-
wait_set.add_guard_condition(sigint_gc, sigint_gc_handle)
309+
wait_set.add_guard_condition(self._sigint_gc, self._sigint_gc_handle)
300310
wait_set.add_guard_condition(self._guard_condition, self._guard_condition_handle)
301311

302312
# Wait for something to become ready
303313
wait_set.wait(timeout_nsec)
304314

305315
# Check sigint guard condition
306-
if wait_set.is_ready(sigint_gc_handle):
316+
if wait_set.is_ready(self._sigint_gc_handle):
307317
raise KeyboardInterrupt()
308-
_rclpy.rclpy_destroy_entity(sigint_gc)
309318

310319
# Mark all guards as triggered before yielding since they're auto-taken
311320
for gc in [g for g in guards if wait_set.is_ready(g.guard_pointer)]:

0 commit comments

Comments
 (0)