protected void CloseOutputSession(TimeSpan timeout) { ThrowIfNotOpened(); ThrowIfFaulted(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // If timeout == TimeSpan.MaxValue, then we want to pass Timeout.Infinite as // SemaphoreSlim doesn't accept timeouts > Int32.MaxValue. // Using TimeoutHelper.RemainingTime() would yield a value less than TimeSpan.MaxValue // and would result in the value Int32.MaxValue so we must use the original timeout specified. if (!SendLock.Wait(TimeoutHelper.ToMilliseconds(timeout))) { if (WcfEventSource.Instance.CloseTimeoutIsEnabled()) { WcfEventSource.Instance.CloseTimeout(SR.Format(SR.CloseTimedOut, timeout)); } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.CloseTimedOut, timeout), TimeoutHelper.CreateEnterTimedOutException(timeout))); } try { // check again in case the previous send faulted while we were waiting for the lock ThrowIfFaulted(); // we're synchronized by sendLock here if (_isOutputSessionClosed) { return; } _isOutputSessionClosed = true; bool shouldFault = true; try { CloseOutputSessionCore(timeout); OnOutputSessionClosed(ref timeoutHelper); shouldFault = false; } finally { if (shouldFault) { Fault(); } } } finally { SendLock.Release(); } }
protected override void OnSend(Message message, TimeSpan timeout) { ThrowIfDisposedOrNotOpen(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // If timeout == TimeSpan.MaxValue, then we want to pass Timeout.Infinite as // SemaphoreSlim doesn't accept timeouts > Int32.MaxValue. // Using TimeoutHelper.RemainingTime() would yield a value less than TimeSpan.MaxValue // and would result in the value Int32.MaxValue so we must use the original timeout specified. if (!SendLock.Wait(TimeoutHelper.ToMilliseconds(timeout))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.SendToViaTimedOut, Via, timeout), TimeoutHelper.CreateEnterTimedOutException(timeout))); } try { // check again in case the previous send faulted while we were waiting for the lock ThrowIfDisposedOrNotOpen(); ThrowIfOutputSessionClosed(); bool success = false; try { ApplyChannelBinding(message); OnSendCore(message, timeoutHelper.RemainingTime()); success = true; if (WcfEventSource.Instance.MessageSentByTransportIsEnabled()) { EventTraceActivity eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message); WcfEventSource.Instance.MessageSentByTransport(eventTraceActivity, RemoteAddress.Uri.AbsoluteUri); } } finally { if (!success) { Fault(); } } } finally { SendLock.Release(); } }
private IConnection SendPreamble(IConnection connection, ArraySegment <byte> preamble, ref TimeoutHelper timeoutHelper) { TimeSpan timeout = timeoutHelper.RemainingTime(); if (!SendLock.Wait(TimeoutHelper.ToMilliseconds(timeout))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.CloseTimedOut, timeout), TimeoutHelper.CreateEnterTimedOutException(timeout))); } try { // initialize a new decoder _decoder = new ClientDuplexDecoder(0); byte[] ackBuffer = new byte[1]; connection.Write(preamble.Array, preamble.Offset, preamble.Count, true, timeoutHelper.RemainingTime()); if (_upgrade != null) { StreamUpgradeInitiator upgradeInitiator = _upgrade.CreateUpgradeInitiator(this.RemoteAddress, this.Via); upgradeInitiator.Open(timeoutHelper.RemainingTime()); if (!ConnectionUpgradeHelper.InitiateUpgrade(upgradeInitiator, ref connection, _decoder, this, ref timeoutHelper)) { ConnectionUpgradeHelper.DecodeFramingFault(_decoder, connection, this.Via, MessageEncoder.ContentType, ref timeoutHelper); } SetRemoteSecurity(upgradeInitiator); upgradeInitiator.Close(timeoutHelper.RemainingTime()); connection.Write(ClientDuplexEncoder.PreambleEndBytes, 0, ClientDuplexEncoder.PreambleEndBytes.Length, true, timeoutHelper.RemainingTime()); } // read ACK int ackBytesRead = connection.Read(ackBuffer, 0, ackBuffer.Length, timeoutHelper.RemainingTime()); if (!ConnectionUpgradeHelper.ValidatePreambleResponse(ackBuffer, ackBytesRead, _decoder, Via)) { ConnectionUpgradeHelper.DecodeFramingFault(_decoder, connection, Via, MessageEncoder.ContentType, ref timeoutHelper); } return(connection); } finally { SendLock.Release(); } }