예제 #1
0
        // getCurrent
        /// Gets the current log client from the top of the setack
        ///////////////////////////////////////////////////
        public static LogClient getCurrent()
        {               //Enter lock
            m_threadlock.AcquireReaderLock(Timeout.Infinite);

            //Get the current logclient
            logstack clientstack = null;
            int      threadid    = Thread.CurrentThread.ManagedThreadId;

            try
            {                   //The list may be modified, so we want to remain in sync
                if (!m_threads.TryGetValue(threadid, out clientstack))
                {               //Failed to find anything related to the thread
                                //Let's assume that the stack just hasn't been created
                    return(null);
                }

                //Take a look
                if (clientstack.Count == 0)
                {
                    return(null);
                }
                return(clientstack.Peek());
            }
            finally
            {                   //Release again
                m_threadlock.ReleaseReaderLock();
            }
        }
예제 #2
0
        internal static void write(TLog type, string Message, Thread thread, bool bCautious)
        {               //Get a reader lock
            m_threadlock.AcquireReaderLock(Timeout.Infinite);

            //We need to release the sync object afterwards
            LogClient client = null;

            try
            {                   //Get the current logclient
                logstack clientstack = null;
                int      threadid    = thread.ManagedThreadId;

                //The list may be modified, so we want to remain in sync
                if (!m_threads.TryGetValue(threadid, out clientstack))
                {                       //Failed to find it; make a note
                    lock (m_warning)
                    {
                        m_warning.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][Log] Failed to find associated clientstack for thread. (write)");
                        m_warning.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][Log] Message: " + Message);
                        m_warning.Flush();
                    }
                    return;
                }

                //If we don't have any logclients, don't bother
                if (clientstack.Count == 0)
                {                       //Notify them
                    lock (m_warning)
                    {
                        m_warning.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][Log] Attempted to write to log when no LogClients were active.");
                        m_warning.Flush();
                    }
                    return;
                }

                //Got it!
                client = clientstack.Peek();
            }
            finally
            {                   //Release our lock
                m_threadlock.ReleaseReaderLock();
            }

            //Redirect
            write(type, Message, client, bCautious);
        }
예제 #3
0
        internal static void yield(LogClient client, Thread thread, bool bCautious, long sync)
        {               //Validate the logclient
            if (client == null)
            {           //Wtf?
                lock (m_error)
                {
                    m_error.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][Log] Attempted to yield null LogClient. (yield)");
                    m_error.Flush();
                }
                return;
            }

            //Ignore fake clients
            if (client.m_bFake)
            {
                return;
            }

            //Enter the lock to access the threads list
            logstack clientstack = null;
            int      threadid    = thread.ManagedThreadId;

            m_threadlock.AcquireReaderLock(Timeout.Infinite);

            try
            {                   //Find our associated client stack
                if (!m_threads.TryGetValue(threadid, out clientstack))
                {               //Failed to find it; let's create a new one
                    LockCookie lc = new LockCookie();
                    lc = m_threadlock.UpgradeToWriterLock(Timeout.Infinite);

                    try
                    {
                        clientstack = new logstack();

                        //Add it to the list
                        m_threads.Add(threadid, clientstack);
                    }
                    finally
                    {
                        m_threadlock.DowngradeFromWriterLock(ref lc);
                    }
                }
            }
            finally
            {
                m_threadlock.ReleaseReaderLock();
            }

            //Set our sync id
            if (sync == -1)
            {
                sync = Interlocked.Increment(ref clientstack.m_runningsync);
            }

            //Attempt to hold the sync object
            bool bSync = true;

            if (bCautious)
            {
                bSync = DdMonitor.TryEnter(clientstack);
            }
            else
            {
                DdMonitor.Enter(clientstack);
            }

            //If this would block, queue the request in the threadpool
            if (!bSync)
            {                   //Queue!
                ThreadPool.QueueUserWorkItem(
                    delegate(object state)
                {                               //Reattempt the assume
                    yield(client, thread, false, sync);
                }
                    );

                //Done
                return;
            }

            //We need to release the sync object afterwards
            try
            {                   //Wait on our sync
                if (!DdMonitor.bNoSync)
                {
                    while (sync - 1 != Interlocked.Read(ref clientstack.m_actualsync))
                    {
                        Monitor.Wait(clientstack);
                    }
                }

                //Make sure the specified client holds the stack
                LogClient stackowner = clientstack.Peek();

                if (stackowner.m_guid != client.m_guid)
                {                       //You can't yield if you don't own the stack
                                        //Report the error and do nothing
                    lock (m_warning)
                    {
                        m_warning.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][Log] Client attempted to yield in a thread whose logging context it didn't own.");
                        m_warning.Flush();
                    }
                    return;
                }

                //Remove the client from the stack
                clientstack.Pop();

                //If the stack has nothing left..
                if (clientstack.Count == 0)
                {                       //Remove it from the thread list
                    m_threadlock.AcquireWriterLock(Timeout.Infinite);

                    try
                    {
                        m_threads.Remove(threadid);
                    }
                    finally
                    {
                        m_threadlock.ReleaseWriterLock();
                    }
                }

                //Increase the count
                Interlocked.Exchange(ref clientstack.m_actualsync, sync);

                //Done
                if (!DdMonitor.bNoSync)
                {
                    Monitor.Pulse(clientstack);
                }
            }
            finally
            {
                DdMonitor.Exit(clientstack);
            }
        }
예제 #4
0
        internal static void assume(LogClient client, Thread thread, bool bCautious, long sync)
        {               //Validate the logclient
            if (client == null)
            {           //Wtf?
                lock (m_error)
                {
                    m_error.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][Log] Attempted to add null LogClient. (assume)");
                    m_error.Flush();
                }
                return;
            }

            //Ignore fake clients
            if (client.m_bFake)
            {
                return;
            }

            //Enter the lock to access the threads list
            logstack clientstack = null;

            m_threadlock.AcquireReaderLock(Timeout.Infinite);

            try
            {                   //Find our associated client stack
                int threadid = thread.ManagedThreadId;

                //We're modifying the list, so we need to be synced
                if (!m_threads.TryGetValue(threadid, out clientstack))
                {                       //Failed to find it; let's create a new one
                    LockCookie lc = new LockCookie();
                    lc = m_threadlock.UpgradeToWriterLock(Timeout.Infinite);

                    try
                    {
                        clientstack = new logstack();

                        //Add it to the list
                        m_threads.Add(threadid, clientstack);
                    }
                    finally
                    {
                        m_threadlock.DowngradeFromWriterLock(ref lc);
                    }
                }
            }
            finally
            {
                m_threadlock.ReleaseReaderLock();
            }

            //Set our sync id
            if (sync == -1)
            {
                sync = Interlocked.Increment(ref clientstack.m_runningsync);
            }

            //Attempt to hold the sync object
            bool bSync = true;

            if (bCautious)
            {
                bSync = DdMonitor.TryEnter(clientstack);
            }
            else
            {
                DdMonitor.Enter(clientstack);
            }

            //If this would block, queue the request in the threadpool
            if (!bSync)
            {                   //Queue!
                ThreadPool.QueueUserWorkItem(
                    delegate(object state)
                {                               //Reattempt the assume
                    assume(client, thread, false, sync);
                }
                    );

                //Done
                return;
            }

            //We need to release the sync object afterwards
            try
            {                   //Wait on our sync
                if (!DdMonitor.bNoSync)
                {
                    while (sync - 1 != Interlocked.Read(ref clientstack.m_actualsync))
                    {
                        Monitor.Wait(clientstack);
                    }
                }

                //Add our client
                clientstack.Push(client);

                //Increase the count
                Interlocked.Exchange(ref clientstack.m_actualsync, sync);

                //Done.
                if (!DdMonitor.bNoSync)
                {
                    Monitor.Pulse(clientstack);
                }
            }
            finally
            {
                DdMonitor.Exit(clientstack);
            }
        }