8000 Fix for #396 LinkContext shutdown datarace by neilstephens · Pull Request #435 · dnp3/opendnp3 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Sep 1, 2022. It is now read-only.

Fix for #396 LinkContext shutdown datarace - #435

Closed
neilstephens wants to merge 2 commits into
dnp3:developfrom
neilstephens:develop
Closed

neilstephens wants to merge 2 commits into
dnp3:developfrom
neilstephens:develop

Conversation

@neilstephens
Copy link
Copy Markdown
Contributor

The problem is that the link keepalive and response timers on LinkContext
could have outstanding handlers at the time of shutdown.
Most of the time this is OK, because the handlers get cancelled on OnLowerLayerDown()
and usually execute with operation aborted error code.

But in the case where a timer handler is already queued for execution
when OnLowerLayerDown() is called, it executes with a success error code
and goes on to access LinkContext members which are in the process of being destroyed.

This fix copies a weak pointer to the ILinkSession into the handlers.
The link session abstraction is the top level of the composition that
the LinkContext is a part of, and hence lifetime is tied to.
This way the handlers can check if their logical lifetime has ended and return
instead of racing with the destruction of the LinkContext.

The problem is that the link keepalive and response timers on LinkContext
could have outstanding handlers at the time of shutdown.
Most of the time this is OK, because the handlers get cancelled on OnLowerLayerDown()
and usually execute with operation aborted error code.

But in the case where a timer handler is already queued for execution
when OnLowerLayerDown() is called, it executes with a success error code
and goes on to access LinkContext members which are in the process of being destroyed.

This fix copies a weak pointer to the ILinkSession into the handlers.
The link session abstraction is the top level of the composition that
the LinkContext is a part of, and hence lifetime is tied to.
This way the handlers can check if their logical lifetime has ended and return
instead of racing with the destruction of the LinkContext.
@neilstephens
Copy link
Copy Markdown
Contributor Author

This PR replaces #395, which was just a proof-of-concept fix. This fix is a more elegant solution. I took the time to understand how the lifetime of the link layer is managed. I understand that the LinkContext is just a part of the LinkLayer composition, who's lifetime is already managed by a shared_ptr on the transport stack. The LinkContext already held a reference (raw pointer) to the LinkLayer base class ILinkSession, so I just moved enable_shared_from_this to the base class, and a capture a weak_ptr in the handlers to avoid the race.

@emgre
emgre commented Apr 12, 2022
Copy link
Copy Markdown
Member

Closing this in favour of #407.

@emgre emgre closed this Apr 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0