Split lock to prevent deadlock in Http2Stream.#47769
Conversation
|
Tagging subscribers to this area: @dotnet/ncl Issue Details
|
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
Outdated
Show resolved
Hide resolved
2e12e2c to
90d82cd
Compare
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
Outdated
Show resolved
Hide resolved
Http2Connection.ChangeInitialWindowSize locks connection's SyncObject and calls Http2Stream.OnWindowUpdate which locks stream's SyncObject. Http2Stream.Complete is called only while stream's SyncObject lock is take and then it calls Http2Connection.RemoveStream that locks connection SyncObject.
90d82cd to
d68a2d4
Compare
|
/azp list |
|
/azp run runtime-libraries-coreclr outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
All this credit logic has changed since the last time I looked at it, so my understanding may be out of date here. That said... Is there some reason that the new lock needs to reside on Http2Stream, as opposed to being encapsulated within the credit management logic? The latter seems a lot safer, and that's how it worked originally if I recall correctly. There are several references to _creditWaiter in SendDataAsync that do not take the new lock. Should they? They certainly look suspicious. |
|
More generally -- At some point we made a change to not use CreditManager here, and try to use CreditWaiter directly. Perhaps we should revisit this? |
At the moment it seems more suitable since we need to guard
Could you please point out where? I just wen through all occurrences of But that cannot be inside a lock and never was before.
It happened here: #32624. Maybe @stephentoub has more to say about the reasons for/against. |
I did it for the reasons outlined in that PR (#32624): it was using a type that was more complicated and provided more features than was needed while also incurring extra allocations. If we need an object anyway in order to have a separate lock, I have no qualms with us refactoring this logic into another helper type, allocating an instance of it instead of a separate lock object and then using it for the lock as well. We shouldn't just reuse CreditManager, though, as we'll then be back to allocating a new waiter every time the stream yields. |
Sorry, I misread your code. Nevermind... |
And just to be clear -- "provided more features" refers to the fact that CreditManager supports multiple waiters, whereas in the stream credit case we only ever have one waiter, right? That makes me feel fine about not using CreditManager here, but still using it other places, since the requirements are different. I just to make sure we are not either (a) duplicating code unnecessarily or (b) missing out on using this optimization in other places, but it sounds like that's not the case here. |
Correct (and as part of supporting multiple waiters, it doesn't try to reuse any of them). |
|
The title says "OnWindowsUpdate". I opened this issue because I wanted to know how a running Windows Update could possibly affect a .NET process 😆 |
|
I'm working on a functional test for the deadlock since I'm able to reproduce the problem. Please don't merge on my behalf. |
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
Outdated
Show resolved
Hide resolved
…andler/Http2Stream.cs Co-authored-by: Stephen Toub <stoub@microsoft.com>
|
/backport to release/5.0 |
|
Started backporting to release/5.0: https://github.com/dotnet/runtime/actions/runs/541208321 |
|
/azp run runtime-libraries-coreclr outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
d634a8d to
0daf008
Compare
|
/azp run runtime-libraries-coreclr outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This reverts commit 0daf008.
Http2Connection.ChangeInitialWindowSizelocks connection's SyncObject and callsHttp2Stream.OnWindowUpdatewhich locks stream's SyncObject.Http2Stream.Completeis called only while stream's SyncObject lock is take and then it callsHttp2Connection.RemoveStreamthat locks connection SyncObject.Fixes #48220