Skip to content

Deadlock in WebSocketBase #115559

@fairful

Description

@fairful

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.

Image

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions