Beispiel #1
0
        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;
            }
        }
Beispiel #2
0
            private void CloseAndRemove()
            {
                TimedLock.AssertLocked(transport);

                Close();
                if (transport.connections != null)
                {
                    transport.connections.Remove(remoteEP.ToString());
                }
            }
Beispiel #3
0
        /// <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);
            }
        }
Beispiel #4
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());
            }
        }
Beispiel #5
0
        /// <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());
            }
        }
Beispiel #6
0
        /// <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);
            }
        }
Beispiel #7
0
        /// <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);
            }
        }
Beispiel #8
0
 /// <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);
 }
Beispiel #9
0
 /// <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
 }
Beispiel #10
0
        /// <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);
            }
        }
Beispiel #11
0
        /// <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);
            }
        }