/// <summary> /// Occurs when the remote party has accepted our offer of this channel. /// </summary> /// <param name="acceptanceParameters">The channel parameters provided by the accepting party.</param> /// <returns>A value indicating whether the acceptance went through; <c>false</c> if the channel is already accepted, rejected or offer rescinded.</returns> internal bool OnAccepted(AcceptanceParameters acceptanceParameters) { lock (this.SyncObject) { if (this.acceptanceSource.TrySetResult(acceptanceParameters)) { this.remoteWindowSize = acceptanceParameters.RemoteWindowSize; return(true); } return(false); } }
/// <summary> /// Accepts an offer made by the remote party. /// </summary> /// <param name="channelOptions">The options to apply to the channel.</param> /// <returns>A value indicating whether the offer was accepted. It may fail if the channel was already closed or the offer rescinded.</returns> internal bool TryAcceptOffer(ChannelOptions channelOptions) { lock (this.SyncObject) { // If the local window size has already been determined, we have to keep that since it can't be expanded once the Pipe is created. // Otherwise use what the ChannelOptions asked for, so long as it is no smaller than the default channel size, since we can't make it smaller either. this.localWindowSize ??= channelOptions.ChannelReceivingWindowSize is long windowSize?Math.Max(windowSize, this.MultiplexingStream.DefaultChannelReceivingWindowSize) : this.MultiplexingStream.DefaultChannelReceivingWindowSize; } var acceptanceParameters = new AcceptanceParameters(this.localWindowSize.Value); if (this.acceptanceSource.TrySetResult(acceptanceParameters)) { if (this.QualifiedId.Source != ChannelSource.Seeded) { var payload = this.MultiplexingStream.formatter.Serialize(acceptanceParameters); this.MultiplexingStream.SendFrame( new FrameHeader { Code = ControlCode.OfferAccepted, ChannelId = this.QualifiedId, }, payload, CancellationToken.None); } try { this.ApplyChannelOptions(channelOptions); return(true); } catch (ObjectDisposedException) { // A (harmless) race condition was hit. // Swallow it and return false below. } } return(false); }