diff --git a/src/System.Net.Sockets/src/System.Net.Sockets.csproj b/src/System.Net.Sockets/src/System.Net.Sockets.csproj index 42b29461aaad..752e3dc50f33 100644 --- a/src/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -378,6 +378,7 @@ + diff --git a/src/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs b/src/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs index 20281ac752b4..c893e798819f 100644 --- a/src/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs +++ b/src/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; +using System.Collections.Concurrent; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; @@ -124,9 +124,8 @@ public bool TryRegister(SafeSocketHandle socket, out Interop.Error error) // // Maps handle values to SocketAsyncContext instances. - // Must be accessed under s_lock. // - private readonly Dictionary _handleToContextMap = new Dictionary(); + private readonly ConcurrentDictionary _handleToContextMap = new ConcurrentDictionary(); // // True if we've reached the handle value limit for this event port, and thus must allocate a new event port @@ -193,7 +192,7 @@ private IntPtr AllocateHandle(SocketAsyncContext context) Debug.Assert(!IsFull, "Expected !IsFull"); IntPtr handle = _nextHandle; - _handleToContextMap.Add(handle, context); + _handleToContextMap.TryAdd(handle, context); _nextHandle = IntPtr.Add(_nextHandle, 1); _outstandingHandles = IntPtr.Add(_outstandingHandles, 1); @@ -210,7 +209,7 @@ private void FreeHandle(IntPtr handle) lock (s_lock) { - if (_handleToContextMap.Remove(handle)) + if (_handleToContextMap.TryRemove(handle, out _)) { _outstandingHandles = IntPtr.Subtract(_outstandingHandles, 1); Debug.Assert(_outstandingHandles.ToInt64() >= 0, $"Unexpected _outstandingHandles: {_outstandingHandles}"); @@ -235,18 +234,6 @@ private void FreeHandle(IntPtr handle) } } - private SocketAsyncContext GetContextFromHandle(IntPtr handle) - { - Debug.Assert(handle != ShutdownHandle, $"Expected handle != ShutdownHandle: {handle}"); - Debug.Assert(handle.ToInt64() < MaxHandles.ToInt64(), $"Unexpected values: handle={handle}, MaxHandles={MaxHandles}"); - lock (s_lock) - { - SocketAsyncContext context; - _handleToContextMap.TryGetValue(handle, out context); - return context; - } - } - private SocketAsyncEngine() { _port = (IntPtr)(-1); @@ -339,7 +326,8 @@ private void EventLoop() } else { - SocketAsyncContext context = GetContextFromHandle(handle); + Debug.Assert(handle.ToInt64() < MaxHandles.ToInt64(), $"Unexpected values: handle={handle}, MaxHandles={MaxHandles}"); + _handleToContextMap.TryGetValue(handle, out SocketAsyncContext context); if (context != null) { context.HandleEvents(_buffer[i].Events);