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); } Fx.Assert(meshEntry != null || !createIfNotExists, "GetMeshEntry failed to get an entry!"); return(meshEntry); }
private MeshEntry GetMeshEntry(string meshId, bool createIfNotExists) { MeshEntry entry = null; LiteLock liteLock = null; try { LiteLock.Acquire(out liteLock, this.gate); if (this.meshId2Entry.TryGetValue(meshId, out entry) || !createIfNotExists) { return(entry); } entry = new MeshEntry(); try { liteLock.UpgradeToWriterLock(); this.meshId2Entry.Add(meshId, entry); } finally { liteLock.DowngradeFromWriterLock(); } } finally { LiteLock.Release(liteLock); } return(entry); }
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 ----s with Register. if (updateInfo.RegistrationId == Guid.Empty || meshEntry == null) { return(Register(updateInfo.ClientId, updateInfo.MeshId, updateInfo.NodeAddress)); } // // preserve locking order between ThisLock and the LiteLock. lock (ThisLock) { try { LiteLock.Acquire(out ll, meshEntry.Gate); if (!meshEntry.EntryTable.TryGetValue(updateInfo.RegistrationId, out entry)) { try { // upgrade to writer lock ll.UpgradeToWriterLock(); return(Register(updateInfo.ClientId, updateInfo.MeshId, updateInfo.NodeAddress)); } finally { ll.DowngradeFromWriterLock(); } } lock (entry) { entry.Address = updateInfo.NodeAddress; entry.Expires = DateTime.UtcNow + this.RefreshInterval; } } finally { LiteLock.Release(ll); } } return(new RegisterResponseInfo(registrationId, RefreshInterval)); }