diff --git a/rclpy/rclpy/executors.py b/rclpy/rclpy/executors.py index d0c1d02f8..a4cc77eaa 100644 --- a/rclpy/rclpy/executors.py +++ b/rclpy/rclpy/executors.py @@ -506,9 +506,6 @@ def _wait_for_ready_callbacks( entity_count = NumberOfEntities( len(subscriptions), len(guards), len(timers), len(clients), len(services)) - for waitable in waitables: - entity_count += waitable.get_num_entities() - # Construct a wait set wait_set = _rclpy.rclpy_get_zero_initialized_wait_set() with ExitStack() as context_stack: @@ -550,6 +547,13 @@ def _wait_for_ready_callbacks( except InvalidHandle: entity_count.num_guard_conditions -= 1 + for waitable in waitables: + try: + context_stack.enter_context(waitable) + entity_count += waitable.get_num_entities() + except InvalidHandle: + pass + context_capsule = context_stack.enter_context(self._context.handle) _rclpy.rclpy_wait_set_init( wait_set, diff --git a/rclpy/rclpy/qos_event.py b/rclpy/rclpy/qos_event.py index f44550423..1e0edf33e 100644 --- a/rclpy/rclpy/qos_event.py +++ b/rclpy/rclpy/qos_event.py @@ -114,6 +114,14 @@ def add_to_wait_set(self, wait_set): with self.__event: self._event_index = _rclpy.rclpy_wait_set_add_event(wait_set, self.__event) + def __enter__(self): + """Mark event as in-use to prevent destruction while waiting on it.""" + self.__event.__enter__() + + def __exit__(self, t, v, tb): + """Mark event as not-in-use to allow destruction after waiting on it.""" + self.__event.__exit__(t, v, tb) + def destroy(self): self.__event.destroy_when_not_in_use() diff --git a/rclpy/rclpy/waitable.py b/rclpy/rclpy/waitable.py index a42211ed4..fb70bb107 100644 --- a/rclpy/rclpy/waitable.py +++ b/rclpy/rclpy/waitable.py @@ -65,6 +65,14 @@ def __init__(self, callback_group): # List of Futures that have callbacks needing execution self._futures = [] + def __enter__(self): + """Implement to mark entities as in-use to prevent destruction while waiting on them.""" + pass + + def __exit__(self, t, v, tb): + """Implement to mark entities as not-in-use to allow destruction after waiting on them.""" + pass + def add_future(self, future): self._futures.append(future)