// common state
Socket socket;
- TimeSpan sendTimeout;
+ TimeSpan asyncSendTimeout;
TimeSpan readFinTimeout;
- TimeSpan receiveTimeout;
+ TimeSpan asyncReceiveTimeout;
+
+ // Socket.SendTimeout/Socket.ReceiveTimeout only work with the synchronous API calls and therefore they
+ // do not get updated when asynchronous Send/Read operations are performed. In order to make sure we
+ // Set the proper timeouts on the Socket itself we need to keep these two additional fields.
+ TimeSpan socketSyncSendTimeout;
+ TimeSpan socketSyncReceiveTimeout;
+
CloseState closeState;
bool isShutdown;
bool noDelay = false;
this.readBuffer = this.connectionBufferPool.Take();
this.asyncReadBufferSize = this.readBuffer.Length;
this.socket.SendBufferSize = this.socket.ReceiveBufferSize = this.asyncReadBufferSize;
- this.sendTimeout = this.receiveTimeout = TimeSpan.MaxValue;
+ this.asyncSendTimeout = this.asyncReceiveTimeout = TimeSpan.MaxValue;
+ this.socketSyncSendTimeout = this.socketSyncReceiveTimeout = TimeSpan.MaxValue;
this.remoteEndpoint = null;
// will never be a timeout error, so TimeSpan.Zero is ok
#pragma warning suppress 56503 // Called from Receive path, SocketConnection cannot allow a SocketException to escape.
throw DiagnosticUtility.ExceptionUtility.ThrowHelper(
- ConvertReceiveException(socketException, TimeSpan.Zero), ExceptionEventType);
+ ConvertReceiveException(socketException, TimeSpan.Zero, TimeSpan.Zero), ExceptionEventType);
}
catch (ObjectDisposedException objectDisposedException)
{
static void OnReceiveTimeout(object state)
{
SocketConnection thisPtr = (SocketConnection)state;
- thisPtr.Abort(SR.GetString(SR.SocketAbortedReceiveTimedOut, thisPtr.receiveTimeout), TransferOperation.Read);
+ thisPtr.Abort(SR.GetString(SR.SocketAbortedReceiveTimedOut, thisPtr.asyncReceiveTimeout), TransferOperation.Read);
}
static void OnSendTimeout(object state)
{
SocketConnection thisPtr = (SocketConnection)state;
thisPtr.Abort(TraceEventType.Warning,
- SR.GetString(SR.SocketAbortedSendTimedOut, thisPtr.sendTimeout), TransferOperation.Write);
+ SR.GetString(SR.SocketAbortedSendTimedOut, thisPtr.asyncSendTimeout), TransferOperation.Write);
}
static void OnReceiveCompleted(IAsyncResult result)
catch (SocketException socketException)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelper(
- ConvertSendException(socketException, TimeSpan.MaxValue), ExceptionEventType);
+ ConvertSendException(socketException, TimeSpan.MaxValue, this.socketSyncSendTimeout), ExceptionEventType);
}
catch (ObjectDisposedException objectDisposedException)
{
return CompletedAsyncResult<bool>.End(result);
}
- Exception ConvertSendException(SocketException socketException, TimeSpan remainingTime)
+ Exception ConvertSendException(SocketException socketException, TimeSpan remainingTime, TimeSpan timeout)
{
- return ConvertTransferException(socketException, this.sendTimeout, socketException,
+ return ConvertTransferException(socketException, timeout, socketException,
TransferOperation.Write, this.aborted, this.timeoutErrorString, this.timeoutErrorTransferOperation, this, remainingTime);
}
- Exception ConvertReceiveException(SocketException socketException, TimeSpan remainingTime)
+ Exception ConvertReceiveException(SocketException socketException, TimeSpan remainingTime, TimeSpan timeout)
{
- return ConvertTransferException(socketException, this.receiveTimeout, socketException,
+ return ConvertTransferException(socketException, timeout, socketException,
TransferOperation.Read, this.aborted, this.timeoutErrorString, this.timeoutErrorTransferOperation, this, remainingTime);
}
catch (SocketException socketException)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelper(
- ConvertSendException(socketException, TimeSpan.MaxValue), ExceptionEventType);
+ ConvertSendException(socketException, TimeSpan.MaxValue, this.asyncSendTimeout), ExceptionEventType);
}
catch (ObjectDisposedException objectDisposedException)
{
}
catch (SocketException socketException)
{
- this.asyncWriteException = ConvertSendException(socketException, TimeSpan.MaxValue);
+ this.asyncWriteException = ConvertSendException(socketException, TimeSpan.MaxValue, this.asyncSendTimeout);
}
-#pragma warning suppress 56500 // [....], transferring exception to caller
+#pragma warning suppress 56500 // Microsoft, transferring exception to caller
catch (Exception exception)
{
if (Fx.IsFatal(exception))
catch (SocketException socketException)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelper(
- ConvertSendException(socketException, timeoutHelper.RemainingTime()), ExceptionEventType);
+ ConvertSendException(socketException, timeoutHelper.RemainingTime(), this.socketSyncSendTimeout), ExceptionEventType);
}
catch (ObjectDisposedException objectDisposedException)
{
catch (SocketException socketException)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelper(
- ConvertReceiveException(socketException, timeoutHelper.RemainingTime()), ExceptionEventType);
+ ConvertReceiveException(socketException, timeoutHelper.RemainingTime(), this.socketSyncReceiveTimeout), ExceptionEventType);
}
catch (ObjectDisposedException objectDisposedException)
{
}
catch (SocketException socketException)
{
- throw DiagnosticUtility.ExceptionUtility.ThrowHelper(ConvertReceiveException(socketException, TimeSpan.MaxValue), ExceptionEventType);
+ throw DiagnosticUtility.ExceptionUtility.ThrowHelper(ConvertReceiveException(socketException, TimeSpan.MaxValue, this.asyncReceiveTimeout), ExceptionEventType);
}
catch (ObjectDisposedException objectDisposedException)
{
}
catch (SocketException socketException)
{
- this.asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue);
+ this.asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue, this.asyncReceiveTimeout);
}
catch (ObjectDisposedException objectDisposedException)
{
this.asyncReadException = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Read);
}
-#pragma warning suppress 56500 // [....], transferring exception to caller
+#pragma warning suppress 56500 // Microsoft, transferring exception to caller
catch (Exception exception)
{
if (Fx.IsFatal(exception))
}
catch (SocketException socketException)
{
- asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue);
+ asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue, this.asyncReceiveTimeout);
}
-#pragma warning suppress 56500 // [....], transferring exception to caller
+#pragma warning suppress 56500 // Microsoft, transferring exception to caller
catch (Exception exception)
{
if (Fx.IsFatal(exception))
new TimeoutException(SR.GetString(SR.TcpConnectionTimedOut, timeout)), ExceptionEventType);
}
- if (UpdateTimeout(this.receiveTimeout, timeout))
+ if (ShouldUpdateTimeout(this.socketSyncReceiveTimeout, timeout))
{
lock (ThisLock)
{
}
this.socket.ReceiveTimeout = TimeoutHelper.ToMilliseconds(timeout);
}
- this.receiveTimeout = timeout;
+ this.socketSyncReceiveTimeout = timeout;
}
}
else
{
- this.receiveTimeout = timeout;
+ this.asyncReceiveTimeout = timeout;
if (timeout == TimeSpan.MaxValue)
{
CancelReceiveTimer();
new TimeoutException(SR.GetString(SR.TcpConnectionTimedOut, timeout)), ExceptionEventType);
}
- if (UpdateTimeout(this.sendTimeout, timeout))
+ if (ShouldUpdateTimeout(this.socketSyncSendTimeout, timeout))
{
lock (ThisLock)
{
ThrowIfNotOpen();
this.socket.SendTimeout = TimeoutHelper.ToMilliseconds(timeout);
}
- this.sendTimeout = timeout;
+ this.socketSyncSendTimeout = timeout;
}
}
else
{
- this.sendTimeout = timeout;
+ this.asyncSendTimeout = timeout;
if (timeout == TimeSpan.MaxValue)
{
CancelSendTimer();
}
}
- bool UpdateTimeout(TimeSpan oldTimeout, TimeSpan newTimeout)
+ bool ShouldUpdateTimeout(TimeSpan oldTimeout, TimeSpan newTimeout)
{
if (oldTimeout == newTimeout)
{
{
completeSelf = thisPtr.StartConnect();
}
-#pragma warning suppress 56500 // [....], transferring exception to another thread
+#pragma warning suppress 56500 // Microsoft, transferring exception to another thread
catch (Exception e)
{
if (Fx.IsFatal(e))
{
completeSelf = thisPtr.StartAccept();
}
-#pragma warning suppress 56500 // [....], transferring exception to another thread
+#pragma warning suppress 56500 // Microsoft, transferring exception to another thread
catch (Exception e)
{
if (Fx.IsFatal(e))