Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / UtilityExtension.cs / 1 / UtilityExtension.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Net; using System.Runtime.Serialization; using System.ServiceModel.Diagnostics; using System.ServiceModel; using System.ServiceModel.Description; using System.Text; using System.Threading; using System.Xml; class UtilityExtension : IExtension{ uint linkUtility; uint updateCount; IOThreadTimer ackTimer = null; const uint linkUtilityIncrement = 128; const uint maxLinkUtility = 4096; int outTotal=0; uint inTotal=0; uint inUseful=0; IPeerNeighbor owner; object thisLock = new object(); object throttleLock = new object(); public event EventHandler UtilityInfoReceived; public event EventHandler UtilityInfoSent; TypedMessageConverter messageConverter; public const int AcceptableMissDistance = 2; int pendingSends = 0; int checkPointPendingSends = 0; bool isMonitoring = false; int expectedClearance; IOThreadTimer pruneTimer; const int PruneIntervalMilliseconds = 10000; TimeSpan pruneInterval; const int MinimumPendingMessages = 8; public delegate void PruneNeighborCallback(IPeerNeighbor peer); PruneNeighborCallback pruneNeighbor; UtilityExtension() { ackTimer = new IOThreadTimer(AcknowledgeLoop,null,false); pendingSends = 0; pruneTimer = new IOThreadTimer(new WaitCallback(VerifyCheckPoint), null, false); pruneInterval = TimeSpan.FromMilliseconds(PruneIntervalMilliseconds + new Random(Process.GetCurrentProcess().Id).Next(PruneIntervalMilliseconds)); } public bool IsAccurate { get { return updateCount >= 32; } } public uint LinkUtility { get { return linkUtility; } } internal TypedMessageConverter MessageConverter { get { if (messageConverter == null) { messageConverter = TypedMessageConverter.Create(typeof(UtilityInfo), PeerStrings.LinkUtilityAction); } return messageConverter; } } public void Attach(IPeerNeighbor host) { this.owner = host; ackTimer.Set(PeerTransportConstants.AckTimeout); } static public void OnNeighborConnected(IPeerNeighbor neighbor) { DiagnosticUtility.DebugAssert(neighbor != null, "Neighbor must have a value"); neighbor.Extensions.Add(new UtilityExtension()); } static public void OnNeighborClosed(IPeerNeighbor neighbor) { DiagnosticUtility.DebugAssert(neighbor != null, "Neighbor must have a value"); UtilityExtension ext = neighbor.Extensions.Find (); if(ext != null) neighbor.Extensions.Remove(ext); } public void Detach(IPeerNeighbor host) { ackTimer.Cancel(); owner = null; lock(throttleLock) { pruneTimer.Cancel(); } } public object ThisLock { get { return thisLock; } } public static void OnMessageSent(IPeerNeighbor neighbor) { UtilityExtension ext = neighbor.Extensions.Find (); if(ext != null) ext.OnMessageSent(); } void OnMessageSent() { lock(ThisLock) { outTotal++; } Interlocked.Increment(ref pendingSends); } public static void OnEndSend(IPeerNeighbor neighbor, FloodAsyncResult fresult) { if(neighbor.State >= PeerNeighborState.Disconnecting) return; UtilityExtension instance = neighbor.Utility; if(instance == null) return; instance.OnEndSend(fresult); } public void OnEndSend(FloodAsyncResult fresult) { Interlocked.Decrement(ref pendingSends); } void AcknowledgeLoop(object state) { IPeerNeighbor peer = owner; if(peer == null || !peer.IsConnected) return; FlushAcknowledge(); if(owner != null) ackTimer.Set(PeerTransportConstants.AckTimeout); } static public void ProcessLinkUtility(IPeerNeighbor neighbor, UtilityInfo umessage) { DiagnosticUtility.DebugAssert(neighbor != null, "Neighbor must have a value"); UtilityExtension ext = neighbor.Extensions.Find (); if (ext != null) { ext.ProcessLinkUtility(umessage.Useful, umessage.Total); } } // Update link utility for the neighbor. received from the neighbor void ProcessLinkUtility(uint useful, uint total) { uint i=0; lock(ThisLock) { if (total > PeerTransportConstants.AckWindow || useful > total || (uint)outTotal < total ) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.PeerLinkUtilityInvalidValues, useful, total))); } //VERIFY with in this range, we are hoping that the order of useful/useless messages doesnt matter much. for(i=0; i (); if (ext != null) { // Can happen if the neighbor has been closed for instance linkUtility = ext.UpdateLinkUtility(useful); } return linkUtility; } public uint UpdateLinkUtility(bool useful) { lock(ThisLock) { inTotal++; if(useful) inUseful++; linkUtility = Calculate(linkUtility, useful); if(inTotal == PeerTransportConstants.AckWindow) { FlushAcknowledge(); } } return linkUtility; } public void FlushAcknowledge() { if (inTotal == 0) return; uint tempUseful=0, tempTotal=0; lock(ThisLock) { tempUseful = inUseful; tempTotal = inTotal; inUseful = 0; inTotal = 0; } SendUtilityMessage(tempUseful, tempTotal); } class AsyncUtilityState { public Message message; public UtilityInfo info; public AsyncUtilityState(Message message, UtilityInfo info) { this.message = message; this.info = info; } } void SendUtilityMessage(uint useful,uint total) { IPeerNeighbor host = owner; if(host == null || !PeerNeighborStateHelper.IsConnected(host.State) || total == 0) return; UtilityInfo umessage = new UtilityInfo(useful,total); IAsyncResult result = null; Message message = MessageConverter.ToMessage(umessage, MessageVersion.Soap12WSAddressing10); bool fatal = false; try { result = host.BeginSend(message, DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(UtilityMessageSent)), new AsyncUtilityState(message, umessage)); if(result.CompletedSynchronously) { host.EndSend(result); EventHandler handler = UtilityInfoSent; if (handler != null) handler(this, EventArgs.Empty); } } catch(Exception e) { if(DiagnosticUtility.IsFatal(e)) { fatal = true; throw; } if(null != HandleSendException(host,e,umessage)) throw ; DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } finally { if(!fatal && (result == null || result.CompletedSynchronously)) message.Close(); } } void UtilityMessageSent(IAsyncResult result) { if(result == null || result.AsyncState == null) return; IPeerNeighbor host = this.owner; if(host == null || !PeerNeighborStateHelper.IsConnected(host.State)) return; if(result.CompletedSynchronously) return; AsyncUtilityState state = (AsyncUtilityState)result.AsyncState; DiagnosticUtility.DebugAssert(state != null, "IAsyncResult.AsyncState does not contain AsyncUtilityState"); Message message = state.message; UtilityInfo umessage = state.info; bool fatal = false; if (!(umessage != null)) { DiagnosticUtility.DebugAssert("expecting a UtilityInfo message in the AsyncState!"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } try { host.EndSend(result); } catch(Exception e) { if(DiagnosticUtility.IsFatal(e)) { fatal = true; throw; } if(null != HandleSendException(host,e,umessage)) throw; DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } finally { if(!fatal) { DiagnosticUtility.DebugAssert(!result.CompletedSynchronously, "result.CompletedSynchronously"); message.Close(); } } EventHandler handler = UtilityInfoSent; if (handler != null) handler(this, EventArgs.Empty); } Exception HandleSendException(IPeerNeighbor host, Exception e, UtilityInfo umessage) { if ((e is ObjectDisposedException) || (e is TimeoutException) || (e is CommunicationException)) { if (!(!(e.InnerException is QuotaExceededException))) { DiagnosticUtility.DebugAssert("insufficient quota for sending messages!"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } lock(ThisLock) { this.inTotal += umessage.Total; this.inUseful += umessage.Useful; } return null; } else { return e; } } static internal void ReportCacheMiss(IPeerNeighbor neighbor, int missedBy) { DiagnosticUtility.DebugAssert(missedBy > AcceptableMissDistance, "Call this method for cache misses ONLY!"); DiagnosticUtility.DebugAssert(neighbor != null, "Neighbor must have a value"); if(!neighbor.IsConnected) return; UtilityExtension ext = neighbor.Extensions.Find (); if (ext != null) { ext.ReportCacheMiss(missedBy); } } void ReportCacheMiss(int missedBy) { lock(ThisLock) { for(int i=0; i = lclCheckPointPendingSends) { pruneNeighbor(peer); } else { lock(throttleLock) { if(owner == null) return; this.checkPointPendingSends = this.pendingSends; this.expectedClearance = this.expectedClearance/2; pruneTimer.Set(pruneInterval); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- AuthenticationModuleElement.cs
- ExpressionBuilder.cs
- RestHandlerFactory.cs
- ListBindingHelper.cs
- CssTextWriter.cs
- ProfessionalColors.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- ErrorTableItemStyle.cs
- SessionIDManager.cs
- ObjectParameter.cs
- ContentIterators.cs
- DBSchemaRow.cs
- XPathNodeInfoAtom.cs
- PrintingPermission.cs
- AtomMaterializerLog.cs
- DynamicExpression.cs
- XmlSerializableReader.cs
- DodSequenceMerge.cs
- DefaultValueMapping.cs
- WebPartConnectionsCancelEventArgs.cs
- DependencyPropertyChangedEventArgs.cs
- AsyncOperationManager.cs
- BinaryObjectReader.cs
- TemplateBindingExpression.cs
- ActivationArguments.cs
- PrimitiveXmlSerializers.cs
- NullableIntMinMaxAggregationOperator.cs
- DirectionalLight.cs
- HttpHandlersSection.cs
- ImageConverter.cs
- ManualResetEvent.cs
- KeyInfo.cs
- ProxyFragment.cs
- SafeReversePInvokeHandle.cs
- DbProviderFactories.cs
- ContractType.cs
- ConfigsHelper.cs
- XmlComplianceUtil.cs
- StackOverflowException.cs
- StreamAsIStream.cs
- TextBoxView.cs
- ListDesigner.cs
- StylusPointProperty.cs
- CriticalHandle.cs
- WebPartAuthorizationEventArgs.cs
- CatalogPartChrome.cs
- DefaultObjectMappingItemCollection.cs
- DropSource.cs
- StreamBodyWriter.cs
- SizeKeyFrameCollection.cs
- FindCriteria.cs
- ImageList.cs
- WebDisplayNameAttribute.cs
- IPipelineRuntime.cs
- DbProviderFactories.cs
- ArrowControl.xaml.cs
- DeclarativeCatalogPart.cs
- safex509handles.cs
- SendMailErrorEventArgs.cs
- BatchServiceHost.cs
- AssemblyAssociatedContentFileAttribute.cs
- RunWorkerCompletedEventArgs.cs
- VerifyHashRequest.cs
- StylusButtonCollection.cs
- WSSecurityOneDotOneReceiveSecurityHeader.cs
- ChannelServices.cs
- Pkcs7Recipient.cs
- SettingsProviderCollection.cs
- PackWebRequest.cs
- UidPropertyAttribute.cs
- CustomAttributeSerializer.cs
- VisualStyleElement.cs
- ContextMenuAutomationPeer.cs
- LineGeometry.cs
- XmlSecureResolver.cs
- SingleObjectCollection.cs
- Slider.cs
- RtfToXamlLexer.cs
- EntityDataSourceReferenceGroup.cs
- SecurityPermission.cs
- WebPartDescription.cs
- GroupDescription.cs
- UInt16Storage.cs
- ImageMapEventArgs.cs
- SolidColorBrush.cs
- EventDescriptorCollection.cs
- Compilation.cs
- ListViewDeleteEventArgs.cs
- NegationPusher.cs
- CornerRadius.cs
- DataKeyPropertyAttribute.cs
- FakeModelPropertyImpl.cs
- SchemaNamespaceManager.cs
- SmtpClient.cs
- Marshal.cs
- MobileControlsSectionHandler.cs
- BindingEntityInfo.cs
- XmlMembersMapping.cs
- FormatConvertedBitmap.cs
- InvokeBinder.cs