⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 persistentresource.cs

📁 Perst开源实时数据库
💻 CS
字号:
namespace Perst
{
    using System;
    using System.Threading;
    using System.Collections;
	
    /// <summary>Base class for persistent capable objects supporting locking
    /// </summary>
    public class PersistentResource : Persistent, IResource 
    {
#if COMPACT_NET_FRAMEWORK
        class WaitContext 
        {
            internal AutoResetEvent evt;
            internal WaitContext    next;
            internal bool           exclusive;

            internal WaitContext() 
            {
                evt = new AutoResetEvent(false);
            }
        }
        
        static WaitContext freeContexts;

        [NonSerialized()]
        WaitContext queueStart;
        [NonSerialized()]
        WaitContext queueEnd;

        private void wait(bool exclusive)
        {
            WaitContext ctx;
            lock (typeof(PersistentResource)) 
            {
                ctx = freeContexts;
                if (ctx == null) 
                {
                    ctx = new WaitContext();
                } 
                else 
                {
                    freeContexts = ctx.next;
                }
                ctx.next = null;
            }
            if (queueStart != null) 
            { 
                queueEnd = queueEnd.next = ctx;
            } 
            else 
            { 
                queueStart = queueEnd = ctx;
            }                            
            ctx.exclusive = exclusive;
 
            Monitor.Exit(this);
            ctx.evt.WaitOne();

            lock (typeof(PersistentResource)) 
            {
                ctx.next = freeContexts;
                freeContexts = ctx;
            }
        }

        public void SharedLock()    
        {
            Monitor.Enter(this);
            Thread currThread = Thread.CurrentThread;
            if (owner == currThread) 
            { 
                nWriters += 1;
                Monitor.Exit(this);
            } 
            else if (nWriters == 0) 
            { 
                if (storage == null || storage.lockObject(this)) 
                { 
                    nReaders += 1;
                }
                Monitor.Exit(this);
            } 
            else 
            { 
                wait(false);
                if (storage != null) 
                { 
                    storage.lockObject(this);
                }
            } 
        }
                    
                    
        public void ExclusiveLock() 
        {
            Thread currThread = Thread.CurrentThread;
            Monitor.Enter(this);
            if (owner == currThread) 
            { 
                nWriters += 1;
                Monitor.Exit(this);
            } 
            else if (nReaders == 0 && nWriters == 0) 
            { 
                nWriters = 1;
                owner = currThread;
                if (storage != null) 
                { 
                    storage.lockObject(this);
                }
                Monitor.Exit(this);
            } 
            else {
                wait(true);
                owner = currThread;    
                if (storage != null) 
                { 
                    storage.lockObject(this);
                }
            } 
        }
                    

        private void notify() 
        {
            WaitContext next, ctx = queueStart;
            while (ctx != null) 
            { 
                if (ctx.exclusive) 
                {
                    if (nWriters == 0 && nReaders == 0) 
                    {
                        nWriters = 1;
                        next = ctx.next;
                        ctx.evt.Set();
                        ctx = next;
                    } 
                    break;
                } 
                else if (nWriters == 0)
                {
                    nReaders += 1;
                    next = ctx.next;
                    ctx.evt.Set();
                    ctx = next;
                } 
                else 
                {
                    break;
                }
            }
            queueStart = ctx;
        }

        
        public void Unlock() 
        {
            lock (this) 
            { 
                if (nWriters != 0) 
                { 
                    if (--nWriters == 0) 
                    { 
                        owner = null;
                        notify();
                    }
                } 
                else if (nReaders != 0)
                { 
                    if (--nReaders == 0) 
                    { 
                        notify();
                    }
                }
            }
        }

        public void Reset() 
        { 
            lock (this) 
            { 
                if (nWriters > 0) 
                { 
                    nWriters = 0;
                    nReaders = 0;
                    owner = null;
                } 
                else if (nReaders > 0) 
                { 
                    nReaders -= 1;
                }
                notify();
            }
        }
#else
        public void SharedLock()    
        {
            lock (this) 
            { 
                Thread currThread = Thread.CurrentThread;
                while (true) 
                { 
                    if (owner == currThread) 
                    { 
                        nWriters += 1;
                        break;
                    } 
                    else if (nWriters == 0) 
                    { 
                        if (storage == null || storage.lockObject(this)) 
                        {                        
                            nReaders += 1;
                        }
                        break;
                    } 
                    else 
                    { 
                        Monitor.Wait(this);
                    }
                }
            }
        }
                    
        public bool SharedLock(long timeout) 
        {
            Thread currThread = Thread.CurrentThread;
            DateTime startTime = DateTime.Now;
            TimeSpan ts = TimeSpan.FromMilliseconds(timeout);
            lock (this) 
            { 
                while (true) 
                { 
                    if (owner == currThread) 
                    { 
                        nWriters += 1;
                        return true;
                    } 
                    else if (nWriters == 0) 
                    { 
                        if (storage == null || storage.lockObject(this)) 
                        {                        
                            nReaders += 1;
                        }
                        return true;
                    } 
                    else 
                    { 
                        DateTime currTime = DateTime.Now;
                        if (startTime + ts <= currTime) 
                        { 
                            return false;
                        }
                        Monitor.Wait(this, startTime + ts - currTime);
                    }
                }
            } 
        }
    
                    
        public void ExclusiveLock() 
        {
            Thread currThread = Thread.CurrentThread;
            lock (this)
            { 
                while (true) 
                { 
                    if (owner == currThread) 
                    { 
                        nWriters += 1;
                        break;
                    } 
                    else if (nReaders == 0 && nWriters == 0) 
                    { 
                        nWriters = 1;
                        owner = currThread;
                        if (storage != null) 
                        { 
                            storage.lockObject(this);
                        }
                        break;
                    } 
                    else 
                    { 
                        Monitor.Wait(this);
                    }
                }
            } 
        }
                    
        public bool ExclusiveLock(long timeout) 
        {
            Thread currThread = Thread.CurrentThread;
            TimeSpan ts = TimeSpan.FromMilliseconds(timeout);
            DateTime startTime = DateTime.Now;
            lock (this) 
            { 
                while (true) 
                { 
                    if (owner == currThread) 
                    { 
                        nWriters += 1;
                        return true;
                    } 
                    else if (nReaders == 0 && nWriters == 0) 
                    { 
                        nWriters = 1;
                        owner = currThread;
                        if (storage != null) 
                        { 
                            storage.lockObject(this);
                        }
                        return true;
                    } 
                    else 
                    { 
                        DateTime currTime = DateTime.Now;
                        if (startTime + ts <= currTime) 
                        { 
                            return false;
                        }
                        Monitor.Wait(this, startTime + ts - currTime);
                    }
                }
            } 
        }
        public void Unlock() 
        {
            lock (this) 
            { 
                if (nWriters != 0) 
                { 
                    if (--nWriters == 0) 
                    { 
                        owner = null;
                        Monitor.PulseAll(this);
                    }
                } 
                else if (nReaders != 0)
                { 
                    if (--nReaders == 0) 
                    { 
                        Monitor.PulseAll(this);
                    }
                }
            }
        }

        public void Reset() 
        { 
            lock (this) 
            { 
                if (nWriters > 0) 
                { 
                    nWriters = 0;
                    nReaders = 0;
                    owner = null;
                } 
                else if (nReaders > 0) 
                { 
                    nReaders -= 1;
                }
                Monitor.PulseAll(this);
            }
        }

#endif
        internal protected PersistentResource() {}

        internal protected PersistentResource(Storage storage) 
            : base(storage) {}

        [NonSerialized()]
        private Thread owner;
        [NonSerialized()]
        private int    nReaders;
        [NonSerialized()]
        private int    nWriters;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -