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

Fix race when signaling waitable objects in managed implementation #55200

Merged
merged 1 commit into from
Jul 7, 2021
Merged

Fix race when signaling waitable objects in managed implementation #55200

merged 1 commit into from
Jul 7, 2021

Conversation

uweigand
Copy link
Contributor

@uweigand uweigand commented Jul 6, 2021

  • TrySignalToSatisfyWait may invalidate multiple elements of the
    WaitedListNode linked list, if the same object occurs multiple
    times in a single WaitForMultipleObjects call.

This race showed up in sporading failures in System.Threading.Tasks.Tests, indicated by an assertion failure in TrySignalToSatisfyWait when called from SignalManualResetEvent. The problem is that in this loop:

                for (ThreadWaitInfo.WaitedListNode? waiterNode = _waitersHead, nextWaiterNode;
                    waiterNode != null;
                    waiterNode = nextWaiterNode)
                {
                    // Signaling a waiter will unregister the waiter node, so keep the next node before trying
                    nextWaiterNode = waiterNode.Next;

                    waiterNode.WaitInfo.TrySignalToSatisfyWait(waiterNode, isAbandonedMutex: false);
                }

the TrySignalToSatisfyWait call may modify the linked list we're traversing. The code attempts to address that issue by keeping the next node before the call -- but that next node may itself be modified by the call. This happens only if that next node has the same WaitInfo as the current node, which is normally not the case, but may occur if the same waitable object is used multiple times as argument to a single WaitAny / WaitForMultipleObjects call.

@ghost
Copy link

ghost commented Jul 6, 2021

Tagging subscribers to this area: @mangod9
See info in area-owners.md if you want to be subscribed.

Issue Details
  • TrySignalToSatisfyWait may invalidate multiple elements of the
    WaitedListNode linked list, if the same object occurs multiple
    times in a single WaitForMultipleObjects call.

This race showed up in sporading failures in System.Threading.Tasks.Tests, indicated by an assertion failure in TrySignalToSatisfyWait when called from SignalManualResetEvent. The problem is that in this loop:

                for (ThreadWaitInfo.WaitedListNode? waiterNode = _waitersHead, nextWaiterNode;
                    waiterNode != null;
                    waiterNode = nextWaiterNode)
                {
                    // Signaling a waiter will unregister the waiter node, so keep the next node before trying
                    nextWaiterNode = waiterNode.Next;

                    waiterNode.WaitInfo.TrySignalToSatisfyWait(waiterNode, isAbandonedMutex: false);
                }

the TrySignalToSatisfyWait call may modify the linked list we're traversing. The code attempts to address that issue by keeping the next node before the call -- but that next node may itself be modified by the call. This happens only if that next node has the same WaitInfo as the current node, which is normally not the case, but may occur if the same waitable object is used multiple times as argument to a single WaitAny / WaitForMultipleObjects call.

Author: uweigand
Assignees: -
Labels:

area-System.Threading

Milestone: -

@jkotas
Copy link
Member

jkotas commented Jul 6, 2021

Is this fixing #52614 ? Can we re-enable the test disabled against this issue?

@uweigand
Copy link
Contributor Author

uweigand commented Jul 6, 2021

Is this fixing #52614 ? Can we re-enable the test disabled against this issue?

From the call chain, it does look like this issue. I can't really test on iOS or tvOS myself, but I guess I could enable the test as part of this PR and see if the CI passes?

@jkotas
Copy link
Member

jkotas commented Jul 6, 2021

I could enable the test as part of this PR and see if the CI passes?

Yep

* TrySignalToSatisfyWait may invalidate multiple elements of the
  WaitedListNode linked list, if the same object occurs multiple
  times in a single WaitForMultipleObjects call.

* Fixes #52614
@uweigand
Copy link
Contributor Author

uweigand commented Jul 6, 2021

I could enable the test as part of this PR and see if the CI passes?

Yep

OK, let's give it a try.

@jkotas
Copy link
Member

jkotas commented Jul 7, 2021

Failures are unrelated

@jkotas jkotas merged commit 9ce467f into dotnet:main Jul 7, 2021
@uweigand uweigand deleted the mono-race-waitinfo branch July 7, 2021 11:40
@ghost ghost locked as resolved and limited conversation to collaborators Aug 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants