// Member Functions
        ///////////////////////////////////////////////////
        //Constructor
        public ObjectSafe(object used)
        {               //Sanity check
            if (used == null)
            {
                return;
            }

            //Is the object castable as a threadedobject?
            IThreadedObject obj = used as IThreadedObject;

            if (obj != null)
            {                            //Yes! Let's handle it
                if (obj._eventLogger != null)
                {                        //Make sure it is necessary to log
                    m_bLogActive = true; // !Log.isCurrent(obj.m_eventlogger);

                    //Assume it
                    if (m_bLogActive)
                    {
                        Log.assume(obj._eventLogger);
                    }
                }

                //Enter the object's synchronous state
                DdMonitor.Enter(obj._sync);
            }
            else
            {
                Log.write(TLog.Warning, "Attempted to ObjectSafe a null/Non-Threaded object.");
            }

            m_used = used;
        }
Beispiel #2
0
        // unloadSeries
        /// Unloads a series of handlers with the same guid
        ///////////////////////////////////////////////////
        public void unloadSeries(string guid)
        {               //Be threadsafe
            using (DdMonitor.Lock(m_eventobject._sync))
            {           //Search through all our events
                foreach (KeyValuePair <string, HandlerList> kvp in this)
                {       //For each handler
                    List <CEventHandler> toRemove = new List <CEventHandler>();

                    foreach (CEventHandler eh in kvp.Value.methods)
                    {                           //If the handler is in this series
                        if (eh.guid == guid)
                        {
                            //Add it to the removal list
                            toRemove.Add(eh);
                        }
                    }

                    //Remove all condemned handlers
                    foreach (CEventHandler eh in toRemove)
                    {
                        kvp.Value.methods.Remove(eh);
                    }
                }
            }
        }
Beispiel #3
0
 /// <summary>Exit the lock.</summary>
 public void Dispose()
 {
     if (_monitor != null)
     {
         DdMonitor.Exit(_monitor);
         _monitor = null;
     }
 }
        protected void Dispose(bool disposeManagedResources)
        {               //Do we have anything to dispose?
            if (!m_bDisposed)
            {           //Is the object castable as a threadedobject?
                IThreadedObject obj = m_used as IThreadedObject;

                if (obj != null)
                {                       //Yes, let's clean up
                                        //Yield to the logging stack if it's active
                    if (m_bLogActive && obj._eventLogger != null)
                    {
                        Log.yield(obj._eventLogger);
                    }

                    //Exit the synchronous state
                    DdMonitor.Exit(obj._sync);
                }

                m_bDisposed = true;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Triggers an event
        /// </summary>
        static public void trigger(IEventObject obj, string name, bool bCautious, params object[] args)
        {               //Attempt to hold the sync object
            bool bSync = true;

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

            //If this would block, queue the request in the threadpool
            if (!bSync)
            {                   //Queue!
                ThreadPool.QueueUserWorkItem(
                    delegate(object state)
                {                               //Reattempt the trigger
                    trigger(obj, name, false, args);
                }
                    );

                //Done
                return;
            }

            try
            {                   //Does the event exist?
                HandlerList list;

                if (!obj.events.TryGetValue(name, out list))
                {
                    //No? No need to worry
                    return;
                }

                //Got it! Execute all handlers
                foreach (CEventHandler eh in list.methods)
                {                       //Sanity checks
                    if (eh.argnum != args.Length)
                    {
                        throw new ArgumentException("Parameter mismatch while attempting to invoke custom event '" + name + "'");
                    }

                    //Use the logger if necessary
                    using (LogAssume.Assume(obj._eventLogger))
                    {                           //We're ok, time to invoke it
                                                //Custom handler?
                        if (eh.customcaller == null)
                        {
                            eh.handler(eh.that, args);
                        }
                        else
                        {
                            //Allow them to call it
                            eh.customcaller(eh, false, eh.that, args);
                        }
                    }
                }
            }
            catch (Exception ex)
            {                   //Log
                Log.write(TLog.Exception, "Exception occured while triggering event (" + name + "):\r\n" + ex.ToString());
            }
            finally
            {
                DdMonitor.Exit(obj._sync);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Calls a singlecast event, returning a value
        /// </summary>
        static public object callsync(IEventObject obj, string name, bool bSync, params object[] args)
        {               //Play safe?
            if (bSync)
            {
                using (DdMonitor.Lock(obj._sync))
                {                       //Does the event exist?
                    HandlerList list;

                    if (!obj.events.TryGetValue(name, out list))
                    {
                        //No? No need to worry
                        return(null);
                    }

                    //Got it! Execute all handlers
                    foreach (CEventHandler eh in list.methods)
                    {                           //Sanity checks
                        if (eh.argnum != args.Length)
                        {
                            throw new ArgumentException("Parameter mismatch while attempting to invoke custom event '" + name + "'");
                        }

                        //We're ok, time to invoke it
                        object ret = null;

                        //Use the logger if necessary
                        using (LogAssume.Assume(obj._eventLogger))
                        {                               //Custom handler?
                            if (eh.customcaller == null)
                            {
                                ret = eh.handler(eh.that, args);
                            }
                            else
                            {
                                //Allow them to call it
                                ret = eh.customcaller(eh, true, eh.that, args);
                            }

                            //Got our loot, return with it
                            return(ret);
                        }
                    }

                    return(null);
                }
            }
            else
            {                   //Does the event exist?
                HandlerList list;

                if (!obj.events.TryGetValue(name, out list))
                {
                    //No? No need to worry
                    return(null);
                }

                //Got it! Execute all handlers
                foreach (CEventHandler eh in list.methods)
                {                       //Sanity checks
                    if (eh.argnum != args.Length)
                    {
                        throw new ArgumentException("Parameter mismatch while attempting to invoke custom event '" + name + "'");
                    }

                    //We're ok, time to invoke it
                    object ret = null;

                    //Use the logger if necessary
                    using (LogAssume.Assume(obj._eventLogger))
                    {                           //Custom handler?
                        if (eh.customcaller == null)
                        {
                            ret = eh.handler(eh.that, args);
                        }
                        else
                        {
                            //Allow them to call it
                            ret = eh.customcaller(eh, true, eh.that, args);
                        }

                        //Got our loot, return with it
                        return(ret);
                    }
                }

                return(null);
            }
        }
Beispiel #7
0
        internal static void write(TLog type, string Message, LogClient client, bool bCautious)
        {               //Ignore fake clients
            if (client == null || client.m_bFake)
            {
                return;
            }

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

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

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

                //Done
                return;
            }

            //We need to release the sync object afterwards
            try
            {                   //Handle the message type
                string typechar = " ";

                switch (type)
                {
                case TLog.Inane:
                    if (type >= m_consoleThreshold)
                    {
                        Console.ForegroundColor = ConsoleColor.DarkGray;
                    }
                    break;

                case TLog.Normal:
                    if (type >= m_consoleThreshold)
                    {
                        Console.ForegroundColor = ConsoleColor.Gray;
                    }
                    break;

                case TLog.Warning:
                    //Write to the warning log
                    lock (m_warning)
                    {
                        m_warning.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][" + client.m_clientname + client.m_clientnum + "] " + Message);
                        m_warning.Flush();
                    }

                    if (type >= m_consoleThreshold)
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                    }
                    typechar = "! ";
                    break;

                case TLog.Error:
                    //Write to the error log
                    lock (m_error)
                    {
                        m_error.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][" + client.m_clientname + client.m_clientnum + "] " + Message);
                        m_error.Flush();
                    }

                    if (type >= m_consoleThreshold)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                    }
                    typechar = "* ";
                    break;

                case TLog.Exception:
                    //Write to the exception log
                    lock (m_exception)
                    {
                        m_exception.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][" + client.m_clientname + client.m_clientnum + "] " + Message);
                        m_exception.Flush();
                    }

                    if (type >= m_consoleThreshold)
                    {
                        Console.ForegroundColor = ConsoleColor.DarkRed;
                    }
                    typechar = "* ";
                    break;

                case TLog.Security:
                    lock (m_security)
                    {
                        m_security.WriteLine("[" + DateTime.Now.ToLongTimeString() + "][" + client.m_clientname + client.m_clientnum + "] " + Message);
                        m_security.Flush();
                    }

                    if (type >= m_consoleThreshold)
                    {
                        Console.ForegroundColor = ConsoleColor.White;
                    }
                    typechar = "! ";
                    break;
                }

                //Write the message to the logfile
                client.m_writer.WriteLine("[" + DateTime.Now.ToLongTimeString() + "]" + typechar + Message);
                client.m_writer.Flush();

                //Obey the console threshold
                if (type >= m_consoleThreshold)
                {
                    Console.WriteLine(Message);
                }
            }
            finally
            {
                DdMonitor.Exit(client);
            }

            //Sink the message into the logclient handlers
            client.sinkMessage(type, Message);

            //Sink it into our own handlers
            sinkMessage(type, client, Message);
        }
Beispiel #8
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);
            }
        }
Beispiel #9
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);
            }
        }