-
Notifications
You must be signed in to change notification settings - Fork 74
Block in zenoh entities drop/undeclare until corresponding callbacks return and are dropped #987
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
base: main
Are you sure you want to change the base?
Block in zenoh entities drop/undeclare until corresponding callbacks return and are dropped #987
Conversation
PR missing one of the required labels: {'documentation', 'dependencies', 'internal', 'enhancement', 'new feature', 'breaking-change', 'bug'} |
4c55e9f
to
882e5eb
Compare
If I correctly understand the code, it will deadlock if entity is dropped inside of the callback. If so - this is extremely complicated and also is a breaking change for existing code. Can you please explain what the bug is? - as for me, if we just follow underlying zenoh logic (and we do), everything should be fine |
I do not clearly understand how this could happen under normal circumstances. We can not pass subscriber/queryable/listener to their respective callbacks since they are not constructed yet - we could pass a non-shared pointer to the place where they would be constructed though - but this will result in UB if constructor/declare fails - since it is unclear what is going to happen earlier - the callback is dropped or we null the corresponding zenoh entity - to ensure that drop passes correctly, since we never explicitly request to pass nullified pointers. Now we can pass session to a background subscriber/queryable declaration - I assume that if we do - we must do it using shared pointers - at least this is how we are forced to do in rust - otherwise this is again a way to UB. In this case callback will always hold a reference to session which means - it will never be dropped, since we get a circular dependency session<->callback. The only way to break this circular dependency is by calling session.close() - which is fine here since it will first destroy callbacks, holding shared ptrs to the session, without calling session's destructor. The last case is to pass session's shared ptr to a get callback. In this case callback's drop will be triggered in session.send_response_final - but this already happens while we hold a session.state lock (which is required for session drop/close). So it will deadlock anyways - with my pr or without .
Zenoh logic does not provide any guarantee regarding when the callback will be called the last time nor when it's drop will be called. This creates issues namely in C++ when subscriber and callback data are both stored in the same object - since very often it results in invoking callback or its drop after related data is destroyed - this obviously leads to difficult to debug situation which has been already reported by our users multiple times. |
e0afff8
to
ae86737
Compare
Resolves #986