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
- ApplicationFileParser.cs
- TypeReference.cs
- _NetRes.cs
- MDIWindowDialog.cs
- SQLDecimal.cs
- UserControlDesigner.cs
- OpCopier.cs
- SQLInt64Storage.cs
- TableLayoutSettingsTypeConverter.cs
- StylusCollection.cs
- SQLMoney.cs
- SafeRightsManagementQueryHandle.cs
- DataGridViewRowContextMenuStripNeededEventArgs.cs
- SmtpNtlmAuthenticationModule.cs
- ClientScriptManagerWrapper.cs
- HostVisual.cs
- InvariantComparer.cs
- PropertyIdentifier.cs
- CheckoutException.cs
- SemanticAnalyzer.cs
- XPathException.cs
- RoleGroupCollection.cs
- PropertyEmitterBase.cs
- PropertyItem.cs
- TraceListeners.cs
- DbConnectionStringCommon.cs
- DataGridViewTopRowAccessibleObject.cs
- CompilationSection.cs
- CodeVariableDeclarationStatement.cs
- XmlFormatExtensionAttribute.cs
- ExceptQueryOperator.cs
- BinaryObjectWriter.cs
- SourceLocation.cs
- COM2EnumConverter.cs
- ProgressBarRenderer.cs
- IconHelper.cs
- Activator.cs
- GridViewSelectEventArgs.cs
- AutoGeneratedFieldProperties.cs
- WebControlParameterProxy.cs
- CharacterString.cs
- LocalIdKeyIdentifierClause.cs
- DataGridColumnHeader.cs
- TrackingLocationCollection.cs
- Scripts.cs
- PaginationProgressEventArgs.cs
- StringDictionary.cs
- Util.cs
- HuffmanTree.cs
- SchemaNamespaceManager.cs
- PopupRoot.cs
- AsyncCompletedEventArgs.cs
- ParamArrayAttribute.cs
- InstanceKey.cs
- RequiredFieldValidator.cs
- PackageStore.cs
- EditableRegion.cs
- DockProviderWrapper.cs
- Msec.cs
- ControllableStoryboardAction.cs
- QuadraticBezierSegment.cs
- FrameworkObject.cs
- HttpConfigurationContext.cs
- WbemProvider.cs
- BmpBitmapDecoder.cs
- TypeConverterHelper.cs
- TraceInternal.cs
- SingleAnimationBase.cs
- BackStopAuthenticationModule.cs
- TypeBrowser.xaml.cs
- SqlAliasesReferenced.cs
- ImagingCache.cs
- LogExtent.cs
- KeyTimeConverter.cs
- StateChangeEvent.cs
- XdrBuilder.cs
- DeflateStream.cs
- ExceptionHandlers.cs
- TextFormatterContext.cs
- XmlAnyAttributeAttribute.cs
- FilteredReadOnlyMetadataCollection.cs
- Hashtable.cs
- NodeFunctions.cs
- ValueTable.cs
- Decoder.cs
- BrowserCapabilitiesFactoryBase.cs
- TraceSource.cs
- DurationConverter.cs
- TreeNodeMouseHoverEvent.cs
- FilterFactory.cs
- PrinterUnitConvert.cs
- PropertyValueUIItem.cs
- BlockCollection.cs
- PartitionResolver.cs
- mansign.cs
- VideoDrawing.cs
- TreeView.cs
- TextBounds.cs
- CompilationLock.cs
- DbConnectionHelper.cs