rosbridge_library.internal.executor_helpers module
Helpers for serializing rclpy entity lifecycle with the node’s executor.
Creating or destroying entities (clients, action servers, subscriptions,
publishers, …) on a node from a worker thread is not safe against a
rclpy executor that is concurrently spinning the same node: the executor’s
wait-set rebuild can race with the worker thread’s entity registration or
teardown and leave the executor holding a handle whose underlying PyCapsule
has been freed. The symptom is either a SIGSEGV inside rclpy or, less
loudly, a later TypeError: Object of type 'NoneType' is not an instance of
'capsule' from the next binding call on the affected node.
The remedy used throughout this package — and consistent with the
IncomingQueue fix in #1183 — is to route the lifecycle call through
executor.create_task(...) so it is serialized with the executor’s own
work. This module centralizes that pattern.
- rosbridge_library.internal.executor_helpers.run_on_executor(node_handle: Node, fn: Callable[[], _T]) _T
Run
fn()on the node’s executor thread synchronously and return its result.Use this whenever a worker thread needs to create or destroy an rclpy entity (
Client,ActionServer,Subscription,Publisher, …) on a node that an executor is concurrently spinning.If the node has no attached executor (rare; mostly unit tests), the callable is invoked inline. Exceptions raised by
fnare re-raised in the calling thread.
- rosbridge_library.internal.executor_helpers.schedule_on_executor(node_handle: Node, fn: Callable[[], object]) None
Schedule
fn()for execution on the node’s executor thread.Fire-and-forget: the caller does not wait for completion. Falls back to invoking
fninline if the node has no attached executor.