Beispiel #1
0
    def shutdown(self, timeout_sec: float = None) -> bool:
        """
        Stop executing callbacks and wait for their completion.

        :param timeout_sec: Seconds to wait. Block forever if ``None`` or negative.
            Don't wait if 0.
        :return: ``True`` if all outstanding callbacks finished executing, or ``False`` if the
            timeot expires before all outstanding work is done.
        """
        with self._shutdown_lock:
            if not self._is_shutdown:
                self._is_shutdown = True
                # Tell executor it's been shut down
                _rclpy.rclpy_trigger_guard_condition(self._guard_condition)

        if not self._work_tracker.wait(timeout_sec):
            return False

        # Clean up stuff that won't be used anymore
        with self._nodes_lock:
            self._nodes = set()

        with self._shutdown_lock:
            if self._guard_condition:
                _rclpy.rclpy_destroy_entity(self._guard_condition)
                self._guard_condition = None
            if self._sigint_gc:
                self._sigint_gc.destroy()
                self._sigint_gc = None
        self._cb_iter = None
        self._last_args = None
        self._last_kwargs = None
        return True
Beispiel #2
0
    def test_waitable_with_guard_condition(self):
        self.waitable = GuardConditionWaitable(self.node)
        self.node.add_waitable(self.waitable)

        thr = self.start_spin_thread(self.waitable)
        _rclpy.rclpy_trigger_guard_condition(self.waitable.guard_condition)
        thr.join()

        assert self.waitable.future.done()
        assert self.waitable.future.result()['guard_condition']
Beispiel #3
0
 def remove_node(self, node):
     """Stop managing this node's callbacks."""
     with self._nodes_lock:
         try:
             self._nodes.remove(node)
         except KeyError:
             pass
         else:
             # Rebuild the wait set so it doesn't include this node
             _rclpy.rclpy_trigger_guard_condition(self._guard_condition)
Beispiel #4
0
    def add_node(self, node):
        """
        Add a node whose callbacks should be managed by this executor.

        Return true if the node was added.

        :rtype: bool
        """
        with self._nodes_lock:
            self._nodes.add(node)
            # Rebuild the wait set so it includes this new node
            _rclpy.rclpy_trigger_guard_condition(self._guard_condition)
Beispiel #5
0
    def remove_node(self, node: 'Node') -> None:
        """
        Stop managing this node's callbacks.

        :param node: The node to remove from the executor.
        """
        with self._nodes_lock:
            try:
                self._nodes.remove(node)
            except KeyError:
                pass
            else:
                # Rebuild the wait set so it doesn't include this node
                _rclpy.rclpy_trigger_guard_condition(self._guard_condition)
Beispiel #6
0
    def add_node(self, node: 'Node') -> bool:
        """
        Add a node whose callbacks should be managed by this executor.

        :param node: The node to add to the executor.
        :return: ``True`` if the node was added, ``False`` otherwise.
        """
        with self._nodes_lock:
            if node not in self._nodes:
                self._nodes.add(node)
                node.executor = self
                # Rebuild the wait set so it includes this new node
                _rclpy.rclpy_trigger_guard_condition(self._guard_condition)
                return True
            return False
Beispiel #7
0
    def create_task(self, callback: Union[Callable, Coroutine], *args,
                    **kwargs) -> Task:
        """
        Add a callback or coroutine to be executed during :meth:`spin` and return a Future.

        Arguments to this function are passed to the callback.

        :param callback: A callback to be run in the executor.
        """
        task = Task(callback, args, kwargs, executor=self)
        with self._tasks_lock:
            self._tasks.append((task, None, None))
            _rclpy.rclpy_trigger_guard_condition(self._guard_condition)
        # Task inherits from Future
        return task
Beispiel #8
0
        async def handler(entity, gc, is_shutdown, work_tracker):
            if is_shutdown or not entity.callback_group.beginning_execution(entity):
                # Didn't get the callback, or the executor has been ordered to stop
                entity._executor_event = False
                _rclpy.rclpy_trigger_guard_condition(gc)
                return
            with work_tracker:
                arg = take_from_wait_list(entity)

                # Signal that this has been 'taken' and can be added back to the wait list
                entity._executor_event = False
                _rclpy.rclpy_trigger_guard_condition(gc)

                try:
                    await call_coroutine(entity, arg)
                finally:
                    entity.callback_group.ending_execution(entity)
                    # Signal that work has been done so the next callback in a mutually exclusive
                    # callback group can get executed
                    _rclpy.rclpy_trigger_guard_condition(gc)
Beispiel #9
0
 def trigger(self):
     _rclpy.rclpy_trigger_guard_condition(self.guard_handle)
Beispiel #10
0
 def trigger(self):
     with self.handle as capsule:
         _rclpy.rclpy_trigger_guard_condition(capsule)