Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semantics of rcl_shutdown and rcl_context_fini #1194

Open
fuzzypixelz opened this issue Oct 28, 2024 · 3 comments
Open

Semantics of rcl_shutdown and rcl_context_fini #1194

fuzzypixelz opened this issue Oct 28, 2024 · 3 comments

Comments

@fuzzypixelz
Copy link

I'm opening this issue here as I believe the topic is specific to the rcl layer as exposed and documented by this repository. I have a question about the meaning of this doc comment:

/**
* The context is used in the creation of top level entities like nodes and
* guard conditions, as well as to shutdown a specific instance of init.
*
* Here is a diagram of a typical context's lifecycle:
*
* ```
* +---------------+
* | |
* +--> uninitialized +---> rcl_get_zero_initialized_context() +
* | | | |
* | +---------------+ |
* | |
* | +-----------------------------------------------+
* | |
* | +--------v---------+ +-----------------------+
* | | | | |
* | | zero-initialized +-> rcl_init() +-> initialized and valid +-> rcl_shutdown() +
* | | | | | |
* | +------------------+ +-----------------------+ |
* | |
* | +-----------------------------------------------------------------+
* | |
* | +------------v------------+
* | | |
* | | initialized but invalid +---> finalize all entities, then rcl_context_fini() +
* | | | |
* | +-------------------------+ |
* | |
* +---------------------------------------------------------------------------------+
* ```
*
* A declared but not defined rcl_context_t instance is considered to be
* "uninitialized", and passing an uninitialized context to any functions will
* result in undefined behavior.
* Some functions, like rcl_init() require the context instance to be
* zero initialized (all members set to "zero" state) before use.
*
* Zero initialization of an rcl_context_t should be done with
* rcl_get_zero_initialized_context(), which ensures the context is in a safe
* state for initialization with rcl_init().
*
* Initialization of an rcl_context_t should be done with rcl_init(), after
* which the context is considered both initialized and valid.
* After initialization it can be used in the creation of other entities like
* nodes and guard conditions.
*
* At any time the context can be invalidated by calling rcl_shutdown() on
* the rcl_context_t, after which the context is still initialized but now
* invalid.
*
* Invalidation indicates to other entities that the context was shutdown, but
* is still accessible for use during cleanup of themselves.
*
* After being invalidated, and after all of the entities which used it have
* been finalized, the context should be finalized with rcl_context_fini().
*
* Finalizing the context while entities which have copies of it have not yet
* been finalized is undefined behavior.
* Therefore, the context's lifetime (between calls to rcl_init() and
* rcl_context_fini()) should exceed the lifetime of all entities which use
* it directly (e.g. nodes and guard conditions) or indirectly (e.g.
* subscriptions and topics).

I'm interested in understanding exactly what this means for an rmw implementation such as rmw_zenoh, where it's not at all clear what is the expected behavior for the closing of a Zenoh session.

Invalidation indicates to other entities that the context was shutdown, but is still accessible for use during cleanup of themselves.

What is the scope of this usage? Is there an exact list of APIs that we expect to be called on an "initialized but invalid" context?

@mjcarroll
Copy link
Member

Adding to November 12 ROS PMC meeting agenda.

@fuzzypixelz
Copy link
Author

@mjcarroll Thanks for your reply. Do we have any findings from the meeting your mentioned?

@fujitatomoya
Copy link
Collaborator

i only can think of the usage with DDS based RMW implementation.

even after rcl_shutdown is called, DDS participants are still active, so that all entities under that participants such as nodes can be still accessible from the application. actually we cannot finalize the context (releasing participants) until all entities are destroyed before, that means it needs to call rcl_destroy_node with this invalid context if the node is not destroyed yet.
i think this requirement can be different from implementation details, but it suggests that this could generates undefined behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants