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
- AppSettings.cs
- SafeLocalMemHandle.cs
- ObjectReferenceStack.cs
- HttpCookiesSection.cs
- ZipIOCentralDirectoryFileHeader.cs
- RuntimeCompatibilityAttribute.cs
- SupportingTokenBindingElement.cs
- RefreshEventArgs.cs
- ProtectedConfiguration.cs
- OSFeature.cs
- Transform.cs
- Process.cs
- SiblingIterators.cs
- SQLRoleProvider.cs
- InkSerializer.cs
- CatchBlock.cs
- HwndSource.cs
- FixUp.cs
- ParagraphVisual.cs
- PipelineModuleStepContainer.cs
- WsdlImporterElement.cs
- TextViewSelectionProcessor.cs
- ConditionalAttribute.cs
- SiteIdentityPermission.cs
- NativeMethods.cs
- TokenizerHelper.cs
- SqlRecordBuffer.cs
- safesecurityhelperavalon.cs
- OdbcCommandBuilder.cs
- TextEditorTyping.cs
- LicenseContext.cs
- ValidatingReaderNodeData.cs
- DataGridCaption.cs
- ColumnTypeConverter.cs
- ValueType.cs
- DefaultTextStore.cs
- WindowsAuthenticationModule.cs
- RenderData.cs
- SynchronousChannel.cs
- WebPartDisplayModeCancelEventArgs.cs
- SelectionWordBreaker.cs
- SystemEvents.cs
- UpdateRecord.cs
- ExpressionWriter.cs
- BuildManagerHost.cs
- ToolStripDropDownClosedEventArgs.cs
- _SslStream.cs
- TextUtf8RawTextWriter.cs
- DbMetaDataFactory.cs
- ConfigurationManagerInternalFactory.cs
- PhotoPrintingIntent.cs
- X509Utils.cs
- ToolStripItem.cs
- Trigger.cs
- SystemIPInterfaceStatistics.cs
- NullExtension.cs
- TracedNativeMethods.cs
- StorageModelBuildProvider.cs
- ModelChangedEventArgsImpl.cs
- HeaderCollection.cs
- DispatcherFrame.cs
- PaginationProgressEventArgs.cs
- EnumUnknown.cs
- Int16AnimationUsingKeyFrames.cs
- WsdlExporter.cs
- StrongNameKeyPair.cs
- TagMapCollection.cs
- Attribute.cs
- Addressing.cs
- PersonalizationEntry.cs
- DataSvcMapFileSerializer.cs
- AccessDataSourceView.cs
- EventTrigger.cs
- ResourceCategoryAttribute.cs
- SafeNativeMethods.cs
- InstallerTypeAttribute.cs
- TextDecorations.cs
- SQLBytesStorage.cs
- ObfuscationAttribute.cs
- TableDetailsRow.cs
- SqlXmlStorage.cs
- CacheVirtualItemsEvent.cs
- connectionpool.cs
- DataConnectionHelper.cs
- Rect3DConverter.cs
- OutOfProcStateClientManager.cs
- DrawingVisual.cs
- SmtpReplyReader.cs
- BamlBinaryReader.cs
- TextBounds.cs
- BorderGapMaskConverter.cs
- FormViewDeletedEventArgs.cs
- SerializationInfo.cs
- DynamicDiscoSearcher.cs
- Section.cs
- BasicCommandTreeVisitor.cs
- Int64Converter.cs
- GreenMethods.cs
- RuleCache.cs
- UserPreferenceChangingEventArgs.cs