-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
I've come across a deadlock in System.Net.WebSockets.WebSocketBase. I'm running .Net 9. It's happening when a web socket is being closed from both ends simultaneously. See attached screenshot of Parallel Stacks.
Looking at the code of WebSocketBase, it's pretty obvious what's happening. In one thread, handling the incoming close request, you get this:
- WebSocketBase.Process, line 1362, takes lock on SessionHandle
- WebSocketBase.Process calls StartOnCloseReceived
- WebSocketBase.StartOnCloseReceived, line 1220 takes lock on _thisLock
In the other thread, handling the local close request, you get this:
- WebSocketBase.CloseAsyncCore, line 616, takes lock on _thisLock
- WebSocketBase.CloseAsyncCore calls CloseOutputAsync
- WebSocketBase.CloseOutputAsyncCore calls TakeLocks
- WebSocketBase.TakeLocks, line 886 takes lock on SessionHandle
Classic deadlock - two threads taking the same two locks in different order.
Reproduction Steps
I'm sorry I can't supply a snippet, but closing a socket from both ends simultaneously, using WebSocket.CloseAsync should do it.
Expected behavior
Socket closes without deadlock
Actual behavior
Deadlock!
Regression?
No response
Known Workarounds
Don't close sockets from both ends. This is happening for me in a test, where two connected processes are being shut down simultaneously. They each close all the sockets they have between them - there can be several and each can have been created by either party. A workaround is difficult in this circumstance.
Configuration
.Net 9, Windows 11, x64
Other information
No response