public ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandle()
{
if (_released)
{
// Keep the exception message pointing at the external type.
throw new ObjectDisposedException(typeof(Socket).FullName);
}
// Check to see if the socket native _handle is already
// bound to the ThreadPool's completion port.
if (_iocpBoundHandle == null)
{
lock (_iocpBindingLock)
{
if (_iocpBoundHandle == null)
{
// Bind the socket native _handle to the ThreadPool.
if (NetEventSource.IsEnabled) NetEventSource.Info(this, "calling ThreadPool.BindHandle()");
try
{
// The handle (this) may have been already released:
// E.g.: The socket has been disposed in the main thread. A completion callback may
// attempt starting another operation.
_iocpBoundHandle = ThreadPoolBoundHandle.BindHandle(this);
}
catch (Exception exception)
{
if (ExceptionCheck.IsFatal(exception)) throw;
CloseAsIs();
throw;
}
}
}
}
return _iocpBoundHandle;
}