Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit b6419f5

Browse files
authored
Allow Socket.GetOrAllocateThreadPoolBoundHandle to fully inline (#27895)
1 parent 850c1d7 commit b6419f5

File tree

2 files changed

+21
-20
lines changed

2 files changed

+21
-20
lines changed

src/Common/src/System/Net/SafeCloseSocket.Windows.cs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,35 +30,31 @@ public ThreadPoolBoundHandle IOCPBoundHandle
3030
}
3131
}
3232

33+
public ThreadPoolBoundHandle GetThreadPoolBoundHandle() => !_released ? _iocpBoundHandle : null;
34+
3335
// Binds the Socket Win32 Handle to the ThreadPool's CompletionPort.
3436
public ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandle(bool trySkipCompletionPortOnSuccess)
35-
{
36-
// Check to see if the socket native _handle is already
37-
// bound to the ThreadPool's completion port.
38-
if (_released || _iocpBoundHandle == null)
39-
{
40-
GetOrAllocateThreadPoolBoundHandleSlow(trySkipCompletionPortOnSuccess);
41-
}
42-
43-
return _iocpBoundHandle;
44-
}
45-
46-
private void GetOrAllocateThreadPoolBoundHandleSlow(bool trySkipCompletionPortOnSuccess)
4737
{
4838
if (_released)
4939
{
5040
// Keep the exception message pointing at the external type.
5141
throw new ObjectDisposedException(typeof(Socket).FullName);
5242
}
5343

44+
if (_iocpBoundHandle != null)
45+
{
46+
return _iocpBoundHandle;
47+
}
48+
5449
lock (_iocpBindingLock)
5550
{
56-
if (_iocpBoundHandle == null)
51+
ThreadPoolBoundHandle boundHandle = _iocpBoundHandle;
52+
53+
if (boundHandle == null)
5754
{
5855
// Bind the socket native _handle to the ThreadPool.
5956
if (NetEventSource.IsEnabled) NetEventSource.Info(this, "calling ThreadPool.BindHandle()");
6057

61-
ThreadPoolBoundHandle boundHandle;
6258
try
6359
{
6460
// The handle (this) may have been already released:
@@ -80,8 +76,10 @@ private void GetOrAllocateThreadPoolBoundHandleSlow(bool trySkipCompletionPortOn
8076
}
8177

8278
// Don't set this until after we've configured the handle above (if we did)
83-
_iocpBoundHandle = boundHandle;
79+
Volatile.Write(ref _iocpBoundHandle, boundHandle);
8480
}
81+
82+
return boundHandle;
8583
}
8684
}
8785

src/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
using Microsoft.Win32.SafeHandles;
66
using System.Collections;
77
using System.IO;
8-
using System.Runtime.ExceptionServices;
9-
using System.Runtime.InteropServices;
8+
using System.Runtime.CompilerServices;
109
using System.Threading;
1110

1211
namespace System.Net.Sockets
@@ -285,10 +284,14 @@ private void EndSendFileInternal(IAsyncResult asyncResult)
285284

286285
}
287286

288-
internal ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandle()
287+
internal ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandle() =>
288+
_handle.GetThreadPoolBoundHandle() ??
289+
GetOrAllocateThreadPoolBoundHandleSlow();
290+
291+
[MethodImpl(MethodImplOptions.NoInlining)]
292+
internal ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandleSlow()
289293
{
290-
// There is a known bug that exists through Windows 7 with UDP and
291-
// SetFileCompletionNotificationModes.
294+
// There is a known bug that exists through Windows 7 with UDP and SetFileCompletionNotificationModes.
292295
// So, don't try to enable skipping the completion port on success in this case.
293296
bool trySkipCompletionPortOnSuccess = !(CompletionPortHelper.PlatformHasUdpIssue && _protocolType == ProtocolType.Udp);
294297
return _handle.GetOrAllocateThreadPoolBoundHandle(trySkipCompletionPortOnSuccess);

0 commit comments

Comments
 (0)