public void TimedLock_AssertLocked() { bool diagMode; diagMode = TimedLock.FullDiagnostics; TimedLock.FullDiagnostics = true; try { try { TimedLock.AssertLocked(this); #if DEBUG Assert.Fail("Expected an AssertException"); #endif } catch (Exception e) { Assert.IsInstanceOfType(e, typeof(AssertException)); } using (TimedLock.Lock(this)) { TimedLock.AssertLocked(this); } } finally { TimedLock.FullDiagnostics = diagMode; } }
private void CloseAndRemove() { TimedLock.AssertLocked(transport); Close(); if (transport.connections != null) { transport.connections.Remove(remoteEP.ToString()); } }
/// <summary> /// Handles background tasks. /// </summary> /// <remarks> /// <note> /// This will be called periodically by the base listener class within a <see cref="TimedLock" />. /// </note> /// </remarks> protected override void OnBkTask() { DateTime now = SysTime.Now; TimedLock.AssertLocked(this); // Verify the lock // Scan the queued receive requests for any that have timed-out. if (receiveQueue != null && receiveQueue.Count > 0) { do { AsyncResult <Message, InputChannel> arReceive; arReceive = receiveQueue.Peek(); if (arReceive.TTD <= now) { receiveQueue.Dequeue(); arReceive.Notify(new TimeoutException()); } else { break; } } while (receiveQueue.Count > 0); } // Scan the queued wait requests for any that have timed-out. if (waitQueue != null && waitQueue.Count > 0) { do { AsyncResult <bool, InputChannel> arWait; arWait = waitQueue.Peek(); if (arWait.TTD <= now) { waitQueue.Dequeue(); arWait.Notify(new TimeoutException()); } else { break; } } while (waitQueue.Count > 0); } }
/// <summary> /// Internal method that writes the host/entry registrations to the cluster member properties. /// </summary> private void Register() { TimedLock.AssertLocked(syncLock); if (!enabled || cluster == null) { return; } int index = 0; cluster.Clear(); foreach (DynDnsHostEntry hostEntry in hosts.Values) { cluster.Set(string.Format("host[{0}:{1}]", hostEntry.Host, index++), hostEntry.ToString()); } }
/// <summary> /// Called periodically on a background thread and within a <see cref="TimedLock" /> /// if <see cref="GetBackgroundTaskInterval()" /> returned a positive interval. /// </summary> protected override void OnBkTask() { TimedLock.AssertLocked(this); // Verify the lock // Terminate any pending operations that have exceeded their timeout. DateTime now = SysTime.Now; while (waitQueue.Count > 0 && waitQueue.Peek().TTD <= now) { waitQueue.Dequeue().Notify(new TimeoutException()); } while (receiveQueue.Count > 0 && receiveQueue.Peek().TTD <= now) { receiveQueue.Dequeue().Notify(new TimeoutException()); } }
/// <summary> /// Called by the base class before it queues an <b>AcceptChannel()</b> operation /// giving derived classes a chance to decide whether they can accept a channel. /// </summary> /// <returns>The accepted channel or <c>null</c>.</returns> /// <remarks> /// <note> /// This is called within a <see cref="TimedLock" />. /// </note> /// </remarks> protected override ReplyChannel GetAcceptChannel() { TimedLock.AssertLocked(this); // Verify the lock // Accept a channel if there are any queued requests. if (requestQueue.Count > 0) { ReplyChannel channel; channel = new ReplyChannel(this, new EndpointAddress(this.Uri), base.MessageEncoder); // I explicitly decided not to queue the request return(channel); } else { return(null); } }
/// <summary> /// Called by the base class before it queues an <b>AcceptChannel()</b> operation /// giving derived classes a chance to decide whether they can accept a channel. /// </summary> /// <returns>The accepted channel or <c>null</c>.</returns> /// <remarks> /// <note> /// This is called within a <see cref="TimedLock" />. /// </note> /// </remarks> protected override InputChannel GetAcceptChannel() { TimedLock.AssertLocked(this); // Verify the lock // Accept a channel if there are any queued messages. if (msgQueue.Count > 0) { InputChannel channel; channel = new InputChannel(this, new EndpointAddress(this.Uri)); // I explicitly decided not to queue the message // to the new channel return(channel); } else { return(null); } }
/// <summary> /// Called by the base class before it queues an <b>AcceptChannel()</b> operation /// giving derived classes a chance to decide whether they can accept a channel. /// </summary> /// <returns>The accepted channel or <c>null</c>.</returns> /// <remarks> /// <note> /// This is called within a <see cref="TimedLock" />. /// </note> /// </remarks> protected override InputSessionChannel GetAcceptChannel() { TimedLock.AssertLocked(this); // Verify the lock return(null); }
/// <summary> /// Called periodically on a background thread and within a <see cref="TimedLock" /> /// if <see cref="GetBackgroundTaskInterval()" /> returned a positive interval. /// </summary> protected override void OnBkTask() { TimedLock.AssertLocked(this); // Verify the lock }
/// <summary> /// Loads the message index file. If the index does not exist or is corrupt then /// the index will be rebuilt by performing a full scan of message files under /// the root folder. /// </summary> /// <param name="newIndexFile">Pass as <c>true</c> if a new index file is being created.</param> private void LoadIndex(bool newIndexFile) { string formatErr = string.Format("Invalid or missing index file [{0}].", indexPath); int cMessages; string[] files; Dictionary <Guid, string> msgFiles; TimedLock.AssertLocked(this); messages = new Dictionary <Guid, QueuedMsgInfo>(); // List the message files and build a hash table mapping each message GUID // the fully qualified path to the file. files = Helper.GetFilesByPattern(root + "*.msg", SearchOption.AllDirectories); msgFiles = new Dictionary <Guid, string>(files.Length); foreach (string path in files) { string file = Path.GetFileName(path).ToLowerInvariant(); Guid msgID; if (!file.EndsWith(".msg")) { continue; } try { msgID = new Guid(file.Substring(0, file.Length - 4)); } catch { continue; } msgFiles[msgID] = path; } // Load the index file. try { // Parse the index file header fsIndex.Position = 0; if (fsIndex.ReadInt32() != IndexMagic) // Magic Number { throw new FormatException(formatErr); } if (fsIndex.ReadInt32() != 0) // Format Version { throw new FormatException(formatErr); } fsIndex.ReadInt32(); // Reserved if (fsIndex.ReadInt32() != 0) { throw new FormatException(string.Format("Index file [{0}] was not closed properly. Full message folder scan will be performed.", indexPath)); } cMessages = fsIndex.ReadInt32(); // Message Count // Parse the message metadata for (int i = 0; i < cMessages; i++) { QueuedMsgInfo msgInfo; msgInfo = new QueuedMsgInfo(fsIndex.ReadString16()); msgInfo.PersistID = msgInfo.ID; msgInfo.ProviderData = root + fsIndex.ReadString16(); // Make the paths absolute messages[msgInfo.ID] = msgInfo; } // Perform an extra consistency check by listing all of the message files // under the root folder and comparing the message GUIDs encoded into the // file names with the GUIDs loaded from the index file and then bringing // the index into sync with the actual message files. bool updated = false; int cLoaded = 0; // Delete any metadata for messages that exist in the index // but don't exist on the file system. var delList = new List <Guid>(); foreach (Guid msgID in messages.Keys) { if (!msgFiles.ContainsKey(msgID)) { delList.Add(msgID); } } foreach (Guid msgID in delList) { messages.Remove(msgID); } if (delList.Count > 0) { updated = true; SysLog.LogWarning(string.Format("Message index [{0}] has message metadata for messages that do not exist. [{1}] messages will be removed from the index.", indexPath, delList.Count)); } // Load metadata for messages that exist in the file system // but were not in the index. foreach (Guid msgID in msgFiles.Keys) { if (!messages.ContainsKey(msgID)) { string path = msgFiles[msgID]; try { messages[msgID] = ReadMessageMetadata(msgID, path); cLoaded++; } catch (Exception e) { SysLog.LogException(e); } } } if (cLoaded > 0) { updated = true; SysLog.LogWarning(string.Format("Message index [{0}] is missing metadata for [{1}] messages. Missing entries will be added.", indexPath, cLoaded)); } if (updated) { SaveIndex(true); } // Mark the index as "open" for crash detection. fsIndex.Position = OpenFlagOffset; fsIndex.WriteInt32(1); fsIndex.Flush(); } catch { if (newIndexFile) { SysLog.LogWarning("Rebuilding missing message index file [{0}].", indexPath); } else { SysLog.LogWarning("Rebuilding corrupt message index file [{0}].", indexPath); } // Clear the index file if there was a serious error and then // rebuild it from scratch by scanning the message metadata. fsIndex.SetLength(0); fsIndex.Flush(); messages.Clear(); foreach (Guid msgID in msgFiles.Keys) { try { messages.Add(msgID, ReadMessageMetadata(msgID, msgFiles[msgID])); } catch (Exception e2) { SysLog.LogException(e2); } } // Save the index, marking the file as "open" for crash detection SaveIndex(true); } }
/// <summary> /// Handles background tasks. /// </summary> /// <remarks> /// <note> /// This will be called periodically by the base listener class within a <see cref="TimedLock" />. /// </note> /// </remarks> protected override void OnBkTask() { DateTime now = SysTime.Now; TimedLock.AssertLocked(this); // Verify the lock // Scan for any queued requests that have been in the queue too long // and cancel them. if (requestQueue != null) { while (requestQueue.Count > 0) { if (requestQueue.Peek().TTD > now) { break; } requestQueue.Dequeue().Context.Cancel(); } } // Scan the queued ReceiveRequest() operations for any that have timed-out. if (receiveQueue != null && receiveQueue.Count > 0) { do { AsyncResult <RequestInfo, ReplyChannel> arReceive; arReceive = receiveQueue.Peek(); if (arReceive.TTD <= now) { receiveQueue.Dequeue(); arReceive.Notify(new TimeoutException()); } else { break; } } while (receiveQueue.Count > 0); } // Scan the queued WaitForRequest() operations for any that have timed-out. if (waitQueue != null && waitQueue.Count > 0) { do { AsyncResult <bool, ReplyChannel> arWait; arWait = waitQueue.Peek(); if (arWait.TTD <= now) { waitQueue.Dequeue(); arWait.Notify(new TimeoutException()); } else { break; } } while (waitQueue.Count > 0); } }