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

[AndroidClientHandler] Observe cancellation requests more #4589

Merged
merged 1 commit into from
Apr 30, 2020

Conversation

grendello
Copy link
Contributor

Context: #4550

It is possible that, in certain situations, a cancellation request
arriving from code external to AndroidClientHandler will not be
satisfied while starting the task to acquire connection status, because
the cancellation request appears after handler already established
connection to the remote host but before the request status is obtained.

Failure to check that the cancellation was requested may result in the
status retrieval task starting only to run into the issue that the
AndroidClientHandler object itself is already disposed (since the
cancellation request has been applied) and throw the
ObjectDisposedException instead of cancelling the status request
quietly. Note that this is likely happen only in situations when the
application code aggressively cancels and collects (via calls to the
GC class) AndroidClientHandler instances or in other situations
which induce potential for timing issues in the TPL or async/await
state machine, thus leading to possible race conditions there.

This commit passes cancellation token to the task which runs the status
request, thus preventing it from starting in the situation described
above. The possibility of a race condition still remains, but is
seriously reduced.

@dotMorten
Copy link
Contributor

This didn't fix it for me. See details: #4550 (comment)

Copy link
Contributor

@brendanzagaeski brendanzagaeski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Draft release notes

This looks like a nice user-facing behavior improvement. When you get a chance, you can add a draft release note for it to Documentation/release-notes/4589.md as part of the PR. It looks like the note can probably be a short sentence or two, maybe roughly like:

#### Application behavior on device and emulator

  * [GitHub PR 4582](https://github.com/xamarin/xamarin-android/pull/4589):
    `ObjectDisposedException` could in theory be thrown during cancellation of
    `AndroidClientHandler` requests, depending on the particular timing of
    cancellation and object disposal.

The note can maybe include a sentence like "The time window where this can happen is now even narrower," if that's accurate.

@dotMorten
Copy link
Contributor

I'm not sure this actually makes it narrower. During GC I consistently found this change had no effect what so ever, and I was only able to reproduce this issue during GC.
Apart from that it seems like a safe change, I'm not sure this PR is really worth it, as there's no known test case that actually proves this PR has any effect.

Context: dotnet#4550

It is possible that, in certain situations, a cancellation request
arriving from code external to `AndroidClientHandler` will not be
satisfied while starting the task to acquire connection status, because
the cancellation request appears after handler already established
connection to the remote host but before the request status is obtained.

Failure to check that the cancellation was requested may result in the
status retrieval task starting only to run into the issue that the
`AndroidClientHandler` object itself is already disposed (since the
cancellation request has been applied) and throw the
`ObjectDisposedException` instead of cancelling the status request
quietly.  Note that this is likely happen only in situations when the
application code aggressively cancels and collects (via calls to the
`GC` class) `AndroidClientHandler` instances or in other situations
which induce potential for timing issues in the TPL or `async/await`
state machine, thus leading to possible race conditions there.

This commit passes cancellation token to the task which runs the status
request, thus preventing it from starting in the situation described
above.  The possibility of a race condition still remains, but is
seriously reduced.
Copy link
Contributor

@brendanzagaeski brendanzagaeski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Release note approved. Thanks!

If it turns out in the end that this PR is determined not to be relevant for apps in practice, no worries if is closed rather than merged. If it is merged, then I'll be careful not to change the release note in any way that would imply that a specific known test case is resolved by the change.

One small question, partly of curiosity, is whether this change could be considered an improvement in following Task idioms even if it doesn't correspond to a known test case.

@jonpryor
Copy link
Member

whether this change could be considered an improvement in following Task idioms even if it doesn't correspond to a known test case

I will do so.

@jonpryor jonpryor merged commit 60bc25e into dotnet:master Apr 30, 2020
@grendello grendello deleted the tune-cancellation branch April 30, 2020 19:06
jonpryor pushed a commit that referenced this pull request May 6, 2020
…4589)

Context: #4550

It is possible that, in certain situations, a cancellation request
arriving from code external to `AndroidClientHandler` will not be
satisfied while starting the task to acquire connection status,
because the cancellation request appears after handler already
established connection to the remote host but before the request
status is obtained.

Failure to check that the cancellation was requested may result in the
status retrieval task starting only to run into the issue that the
`AndroidClientHandler` object itself is already disposed (since the
cancellation request has been applied) and throw an
`ObjectDisposedException` instead of cancelling the status request
quietly.  Note that this is likely happen only in situations when the
application code aggressively cancels and collects
`AndroidClientHandler` instances (e.g. via calls to `GC.Collect()`)
or in other situations which induce potential for timing issues in
the TPL or `async/await` state machine, thus leading to possible race
conditions there.

Pass the cancellation token to the task which runs the status request,
thus preventing it from starting in the situation described above.
The possibility of a race condition still remains, but is reduced.
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
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.

None yet

4 participants