Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / PeerResolvers / CustomPeerResolverService.cs / 1 / CustomPeerResolverService.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.PeerResolvers { using System; using System.ServiceModel; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Diagnostics; using System.Globalization; using System.Net.Security; using System.ServiceModel.Configuration; using System.ServiceModel.Channels; using System.Threading; [ServiceBehavior(UseSynchronizationContext = false, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] public class CustomPeerResolverService : IPeerResolverContract { internal enum RegistrationState { OK, Deleted } internal class RegistrationEntry { Guid clientId; Guid registrationId; string meshId; DateTime expires; PeerNodeAddress address; RegistrationState state; public RegistrationEntry(Guid clientId, Guid registrationId, string meshId, DateTime expires, PeerNodeAddress address) { this.ClientId = clientId; this.RegistrationId = registrationId; this.MeshId = meshId; this.Expires = expires; this.Address = address; this.State = RegistrationState.OK; } public Guid ClientId { get { return clientId; } set { clientId = value; } } public Guid RegistrationId { get { return registrationId; } set { registrationId = value; } } public string MeshId { get { return meshId; } set { meshId = value; } } public DateTime Expires { get { return expires; } set { expires = value; } } public PeerNodeAddress Address { get { return address; } set { address = value; } } public RegistrationState State { get { return state; } set { state = value; } } } internal class LiteLock { bool forWrite; bool upgraded; ReaderWriterLock locker; TimeSpan timeout = TimeSpan.FromMinutes(1); LockCookie lc ; LiteLock(ReaderWriterLock locker, bool forWrite) { this.locker = locker; this.forWrite = forWrite; } public static void Acquire(out LiteLock liteLock, ReaderWriterLock locker) { Acquire(out liteLock, locker, false); } public static void Acquire(out LiteLock liteLock, ReaderWriterLock locker, bool forWrite) { LiteLock theLock = new LiteLock(locker, forWrite); try { } finally { if(forWrite) { locker.AcquireWriterLock(theLock.timeout); } else { locker.AcquireReaderLock(theLock.timeout); } liteLock = theLock; } } public static void Release(LiteLock liteLock) { if (liteLock == null) { return; } if(liteLock.forWrite) { liteLock.locker.ReleaseWriterLock(); } else { DiagnosticUtility.DebugAssert(!liteLock.upgraded, "Can't release while upgraded!"); liteLock.locker.ReleaseReaderLock(); } } public void UpgradeToWriterLock() { DiagnosticUtility.DebugAssert(!forWrite, "Invalid call to Upgrade!!"); DiagnosticUtility.DebugAssert(!upgraded, "Already upgraded!"); try { } finally { lc = locker.UpgradeToWriterLock(timeout); upgraded = true; } } public void DowngradeFromWriterLock() { DiagnosticUtility.DebugAssert(!forWrite, "Invalid call to Downgrade!!"); if (upgraded) { locker.DowngradeFromWriterLock(ref lc); upgraded = false; } } } internal class MeshEntry { DictionaryentryTable; Dictionary service2EntryTable; List entryList; ReaderWriterLock gate; internal MeshEntry() { EntryTable = new Dictionary (); Service2EntryTable = new Dictionary (); EntryList = new List (); Gate = new ReaderWriterLock(); } public Dictionary EntryTable { get { return entryTable; } set { entryTable = value; } } public Dictionary Service2EntryTable { get { return service2EntryTable; } set { service2EntryTable = value; } } public List EntryList { get { return entryList; } set { entryList = value; } } public ReaderWriterLock Gate { get { return gate; } set { gate = value; } } } Dictionary meshId2Entry = new Dictionary (); ReaderWriterLock gate; TimeSpan timeout = TimeSpan.FromMinutes(1); TimeSpan cleanupInterval = TimeSpan.FromMinutes(1); TimeSpan refreshInterval = TimeSpan.FromMinutes(10); bool controlShape; bool isCleaning; IOThreadTimer timer; object thisLock = new object(); bool opened; TimeSpan LockWait = TimeSpan.FromSeconds(5); public CustomPeerResolverService() { isCleaning = false; gate = new ReaderWriterLock(); } public TimeSpan CleanupInterval { get { return cleanupInterval; } set { if (value < TimeSpan.Zero) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRange0))); } if (TimeoutHelper.IsTooLarge(value)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRangeTooBig))); } lock (ThisLock) { ThrowIfOpened("Set CleanupInterval"); this.cleanupInterval = value; } } } public TimeSpan RefreshInterval { get { return refreshInterval; } set { if (value < TimeSpan.Zero) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRange0))); } if (TimeoutHelper.IsTooLarge(value)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRangeTooBig))); } lock (ThisLock) { ThrowIfOpened("Set RefreshInterval"); this.refreshInterval = value; } } } public bool ControlShape { get { return this.controlShape; } set { lock (ThisLock) { ThrowIfOpened("Set ControlShape"); this.controlShape = value; } } } MeshEntry GetMeshEntry(string meshId){return GetMeshEntry(meshId,true);} MeshEntry GetMeshEntry(string meshId, bool createIfNotExists) { MeshEntry meshEntry = null; LiteLock ll = null; try { LiteLock.Acquire(out ll, gate); if(!this.meshId2Entry.TryGetValue(meshId, out meshEntry) && createIfNotExists) { meshEntry = new MeshEntry(); try { ll.UpgradeToWriterLock(); meshId2Entry.Add(meshId,meshEntry); } finally { ll.DowngradeFromWriterLock(); } } } finally { LiteLock.Release(ll); } DiagnosticUtility.DebugAssert(meshEntry != null || !createIfNotExists, "GetMeshEntry failed to get an entry!"); return meshEntry; } public virtual RegisterResponseInfo Register(Guid clientId, string meshId, PeerNodeAddress address) { Guid registrationId = Guid.NewGuid(); DateTime expiry = DateTime.UtcNow + RefreshInterval; RegistrationEntry entry = null; MeshEntry meshEntry = null; lock (ThisLock) { entry = new RegistrationEntry(clientId, registrationId, meshId, expiry, address); meshEntry = GetMeshEntry(meshId); if(meshEntry.Service2EntryTable.ContainsKey(address.ServicePath)) PeerExceptionHelper.ThrowInvalidOperation_DuplicatePeerRegistration(address.ServicePath); LiteLock ll = null; try { LiteLock.Acquire(out ll, meshEntry.Gate, true); meshEntry.EntryTable.Add(registrationId,entry); meshEntry.EntryList.Add(entry); meshEntry.Service2EntryTable.Add(address.ServicePath, entry); } finally { LiteLock.Release(ll); } } return new RegisterResponseInfo(registrationId, RefreshInterval); } public virtual RegisterResponseInfo Register(RegisterInfo registerInfo) { if (registerInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("registerInfo", SR.GetString(SR.PeerNullRegistrationInfo)); } ThrowIfClosed("Register"); if (!registerInfo.HasBody() || String.IsNullOrEmpty(registerInfo.MeshId)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("registerInfo", SR.GetString(SR.PeerInvalidMessageBody, registerInfo)); } return Register(registerInfo.ClientId, registerInfo.MeshId, registerInfo.NodeAddress); } public virtual RegisterResponseInfo Update(UpdateInfo updateInfo) { if (updateInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("updateInfo", SR.GetString(SR.PeerNullRegistrationInfo)); } ThrowIfClosed("Update"); if(!updateInfo.HasBody() || String.IsNullOrEmpty(updateInfo.MeshId) || updateInfo.NodeAddress == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("updateInfo", SR.GetString(SR.PeerInvalidMessageBody, updateInfo)); } Guid registrationId = updateInfo.RegistrationId; RegistrationEntry entry; MeshEntry meshEntry = GetMeshEntry(updateInfo.MeshId); LiteLock ll = null; //handle cases when Update races with Register. if (updateInfo.RegistrationId == Guid.Empty || meshEntry == null) return Register(updateInfo.ClientId, updateInfo.MeshId, updateInfo.NodeAddress); try { LiteLock.Acquire(out ll, meshEntry.Gate); if(!meshEntry.EntryTable.TryGetValue(updateInfo.RegistrationId, out entry)) return Register(updateInfo.ClientId, updateInfo.MeshId, updateInfo.NodeAddress); lock(entry) { entry.Address = updateInfo.NodeAddress; entry.Expires = DateTime.UtcNow + this.RefreshInterval; } } finally { LiteLock.Release(ll); } return new RegisterResponseInfo(registrationId, RefreshInterval); } public virtual ResolveResponseInfo Resolve(ResolveInfo resolveInfo) { if (resolveInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("resolveInfo", SR.GetString(SR.PeerNullResolveInfo)); } ThrowIfClosed("Resolve"); if(!resolveInfo.HasBody()) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("resolveInfo", SR.GetString(SR.PeerInvalidMessageBody, resolveInfo)); } int currentCount=0; int index=0; int maxEntries = resolveInfo.MaxAddresses; ResolveResponseInfo response = new ResolveResponseInfo(); List results = new List (); List entries = null; PeerNodeAddress address; RegistrationEntry entry; MeshEntry meshEntry = GetMeshEntry(resolveInfo.MeshId, false); if(meshEntry != null) { LiteLock ll = null; try { LiteLock.Acquire(out ll, meshEntry.Gate); entries = meshEntry.EntryList; if(entries.Count <= maxEntries) { foreach(RegistrationEntry e in entries) { results.Add(e.Address); } } else { Random random = new Random(); while(currentCount keys = null; LiteLock ll = null; try { LiteLock.Acquire(out ll, gate); keys = meshId2Entry.Keys; } finally { LiteLock.Release(ll); } foreach(string meshId in keys) { meshEntry = GetMeshEntry(meshId); CleanupMeshEntry(meshEntry); } } finally { isCleaning = false; if(opened) timer.Set(this.CleanupInterval); } } } } } //always call this from a readlock void CleanupMeshEntry(MeshEntry meshEntry) { List remove = new List (); if(!opened) return; LiteLock ll = null; try { LiteLock.Acquire(out ll, meshEntry.Gate, true); foreach(KeyValuePair item in meshEntry.EntryTable) { if((item.Value.Expires <= DateTime.UtcNow)|| (item.Value.State == RegistrationState.Deleted)) { remove.Add(item.Key); meshEntry.EntryList.Remove(item.Value); meshEntry.Service2EntryTable.Remove(item.Value.Address.ServicePath); } } foreach(Guid id in remove) { meshEntry.EntryTable.Remove(id); } } finally { LiteLock.Release(ll); } } object ThisLock { get { return this.thisLock; } } void ThrowIfOpened(string operation) { if (opened) PeerExceptionHelper.ThrowInvalidOperation_NotValidWhenOpen(operation); } void ThrowIfClosed(string operation) { if (!opened) PeerExceptionHelper.ThrowInvalidOperation_NotValidWhenClosed(operation); } } } // 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
- HostingEnvironment.cs
- ConnectionManagementElement.cs
- WebPartUtil.cs
- XPathCompileException.cs
- DesignerTransactionCloseEvent.cs
- HttpCacheVary.cs
- ZipIOCentralDirectoryDigitalSignature.cs
- ProviderUtil.cs
- ResourceContainerWrapper.cs
- ControlCodeDomSerializer.cs
- CanExpandCollapseAllConverter.cs
- AnimationClockResource.cs
- MultilineStringConverter.cs
- SerTrace.cs
- SqlDelegatedTransaction.cs
- WpfKnownTypeInvoker.cs
- AdornerDecorator.cs
- ColumnResizeUndoUnit.cs
- SimpleHandlerBuildProvider.cs
- Attributes.cs
- MeshGeometry3D.cs
- ListViewGroupConverter.cs
- NamespaceMapping.cs
- ConfigurationValidatorAttribute.cs
- SystemUdpStatistics.cs
- SiteMapDataSourceView.cs
- ConditionedDesigner.cs
- ViewCellSlot.cs
- WebPartHelpVerb.cs
- ScriptServiceAttribute.cs
- ContainerCodeDomSerializer.cs
- ProfileGroupSettingsCollection.cs
- ObjectDataSourceWizardForm.cs
- DataTableNewRowEvent.cs
- DataGridViewColumnStateChangedEventArgs.cs
- XamlFilter.cs
- ToolStripDropDownDesigner.cs
- UpdatePanelTrigger.cs
- Merger.cs
- ApplicationServiceManager.cs
- Compilation.cs
- GeometryCollection.cs
- RegexCaptureCollection.cs
- Point3D.cs
- ResourceAssociationSet.cs
- contentDescriptor.cs
- HexParser.cs
- StrongNameSignatureInformation.cs
- CopyAction.cs
- BridgeDataRecord.cs
- RenderData.cs
- NegationPusher.cs
- CapiNative.cs
- NavigationExpr.cs
- ConfigurationSectionCollection.cs
- FormatterServices.cs
- SegmentInfo.cs
- ISO2022Encoding.cs
- XmlRawWriter.cs
- VectorKeyFrameCollection.cs
- Attribute.cs
- MsmqTransportBindingElement.cs
- CompositeActivityValidator.cs
- WindowPattern.cs
- WpfPayload.cs
- LocationReference.cs
- TableRowCollection.cs
- contentDescriptor.cs
- Pipe.cs
- GeneralTransform.cs
- Int64Storage.cs
- LinkConverter.cs
- SmiXetterAccessMap.cs
- ReadOnlyHierarchicalDataSource.cs
- OdbcConnectionStringbuilder.cs
- CredentialSelector.cs
- RpcCryptoRequest.cs
- UnitControl.cs
- PropertyDescriptorGridEntry.cs
- QueryCursorEventArgs.cs
- SchemaImporterExtension.cs
- SourceFileBuildProvider.cs
- MultiTrigger.cs
- RichTextBoxAutomationPeer.cs
- ActionFrame.cs
- TableNameAttribute.cs
- DetailsViewInsertedEventArgs.cs
- ListItemCollection.cs
- DataControlPagerLinkButton.cs
- BaseParagraph.cs
- RegionInfo.cs
- XPathExpr.cs
- ColumnHeader.cs
- GACIdentityPermission.cs
- mda.cs
- _IPv4Address.cs
- CalculatedColumn.cs
- DataGridItem.cs
- PackagePartCollection.cs
- EntryIndex.cs