EnterReadLock() public method

public EnterReadLock ( ) : void
return void
コード例 #1
0
        public bool Contain(T item)
        {
            locker.EnterReadLock();

            var ret = keyList.Contains(item);

            locker.ExitWriteLock();

            return(ret);
        }
コード例 #2
0
 public bool TryGetEntity(UUID id, out ISceneEntity entity)
 {
     // Standard thread-safe lookup
     m_syncRoot.EnterReadLock();
     try
     {
         return(m_entityUUIDs.TryGetValue(id, out entity));
     }
     finally { m_syncRoot.ExitReadLock(); }
 }
コード例 #3
0
ファイル: GroupCache.cs プロジェクト: f0nkey/Corrade-New
 public Cache.Group this[string name, UUID UUID]
 {
     get
     {
         Cache.Group group;
         SyncRoot.EnterReadLock();
         nameUUIDHandleCache.TryGetValue(name, UUID, out group);
         SyncRoot.ExitReadLock();
         return(group);
     }
 }
コード例 #4
0
ファイル: AgentCache.cs プロジェクト: f0nkey/Corrade-New
 public Cache.Agent this[string firstname, string lastname]
 {
     get
     {
         Cache.Agent agent;
         SyncRoot.EnterReadLock();
         nameHandleCache.TryGetValue(firstname, lastname, out agent);
         SyncRoot.ExitReadLock();
         return(agent);
     }
 }
コード例 #5
0
 public Cache.Region this[string name]
 {
     get
     {
         Cache.Region region;
         SyncRoot.EnterReadLock();
         nameCache.TryGetValue(name, out region);
         SyncRoot.ExitReadLock();
         return(region);
     }
 }
コード例 #6
0
        public Object Clone()
        {
            TaskInventoryDictionary clone = new TaskInventoryDictionary();

            m_itemLock.EnterReadLock();
            foreach (UUID uuid in Keys)
            {
                clone.Add(uuid, (TaskInventoryItem)this[uuid].Clone());
            }
            m_itemLock.ExitReadLock();

            return(clone);
        }
コード例 #7
0
        public TValue this[TKey key]
        {
            get
            {
                _lock.EnterReadLock();
                try
                {
                    if (!_dictionary.TryGetValue(key, out var value))
                    {
                        throw new InvalidOperationException($"key {key} doesn't exist");
                    }

                    return(value);
                }
                finally
                {
                    _lock.ExitReadLock();
                }
            }

            set
            {
                _lock.EnterWriteLock();
                _dictionary[key] = value;
                _lock.ExitWriteLock();
            }
        }
コード例 #8
0
ファイル: Storage.cs プロジェクト: e2wugui/zeze
        public V Find(K key, Table <K, V> table)
        {
            ByteBuffer value           = null;
            bool       foundInSnapshot = false;

            snapshotLock.EnterReadLock();
            try
            {
                Record <K, V> r;
                foundInSnapshot = snapshot.TryGetValue(key, out r);
                if (foundInSnapshot)
                {
                    value = r.FindSnapshot();
                }
            }
            finally
            {
                snapshotLock.ExitReadLock();
            }

            if (foundInSnapshot)
            {
                return(null != value?table.DecodeValue(value) : null);
            }

            value = DatabaseTable.Find(table.EncodeKey(key));
            return(null != value?table.DecodeValue(value) : null);
        }
コード例 #9
0
        public void Dispose_Errors()
        {
            var v = new ReaderWriterLockSlim();
            v.Dispose();

            try
            {
                v.EnterUpgradeableReadLock();
                Assert.Fail("1");
            }
            catch (ObjectDisposedException)
            {
            }

            try
            {
                v.EnterReadLock();
                Assert.Fail("2");
            }
            catch (ObjectDisposedException)
            {
            }

            try
            {
                v.EnterWriteLock();
                Assert.Fail("3");
            }
            catch (ObjectDisposedException)
            {
            }
        }
コード例 #10
0
        public bool TryGetAsset(UUID dataID, string contentType, out byte[] data)
        {
            string filename = GetFilename(dataID, contentType);

            m_rwLock.EnterReadLock();
            try
            {
                if (File.Exists(filename))
                {
                    data = File.ReadAllBytes(filename);
                    return(true);
                }

                string temporaryFilename = GetTemporaryFilename(dataID, contentType);
                if (File.Exists(temporaryFilename))
                {
                    data = File.ReadAllBytes(temporaryFilename);
                    return(true);
                }
            }
            catch (Exception ex)
            {
                m_log.Error("Failed to fetch local data " + dataID + " (" + contentType + "): " + ex.Message);
            }
            finally
            {
                m_rwLock.ExitReadLock();
            }

            data = null;
            return(false);
        }
コード例 #11
0
        public bool Contains(ulong handle)
        {
            //if (disposed)
            //    return false;

            bool gotLock = false;

            try
            {
                try { }
                finally
                {
                    m_rwLock.EnterReadLock();
                    gotLock = true;
                }

                return(m_byHandler.ContainsKey(handle & HANDLEMASK));
            }
            finally
            {
                if (gotLock)
                {
                    m_rwLock.ExitReadLock();
                }
            }
        }
コード例 #12
0
ファイル: PocoData.cs プロジェクト: windygu/mysoft
        public static PocoData ForType(Type t)
        {
            //#if !PETAPOCO_NO_DYNAMIC
            //                if (t == typeof(System.Dynamic.ExpandoObject))
            //                    throw new InvalidOperationException("Can't use dynamic types with this method");
            //#endif
            // Check cache
            RWLock.EnterReadLock();
            PocoData pd;

            try
            {
                if (m_PocoDatas.TryGetValue(t, out pd))
                {
                    return(pd);
                }
            }
            finally
            {
                RWLock.ExitReadLock();
            }


            // Cache it
            RWLock.EnterWriteLock();
            try
            {
                // Check again
                if (m_PocoDatas.TryGetValue(t, out pd))
                {
                    return(pd);
                }

                // Create it
                pd = new PocoData(t);

                m_PocoDatas.Add(t, pd);
            }
            finally
            {
                RWLock.ExitWriteLock();
            }

            return(pd);
        }
コード例 #13
0
ファイル: Locks.cs プロジェクト: InjectionDev/Dev.D3
        public ReadLock(ReaderWriterLockSlim rwl, bool upgradeable = false)
        {
            this.rwl = rwl;
            this.upgradeable = upgradeable;

            if (upgradeable)
                rwl.EnterUpgradeableReadLock();
            else
                rwl.EnterReadLock();
        }
コード例 #14
0
		public void Dispose_WithReadLock ()
		{
			var rwl = new ReaderWriterLockSlim ();
			rwl.EnterReadLock ();
			try {
				rwl.Dispose ();
				Assert.Fail ("1");
			} catch (SynchronizationLockException) {
			}
		}
コード例 #15
0
		public SlimReadLockHolder(ReaderWriterLockSlim locker, bool waitForLock)
		{
			this.locker = locker;
			if(waitForLock)
			{
				locker.EnterReadLock();
				lockAcquired = true;
				return;
			}
			lockAcquired = locker.TryEnterReadLock(0);
		}
コード例 #16
0
        public ReadWriteLock(ReaderWriterLockSlim lockObject, bool forWrite)
        {
            if (lockObject == null)
                throw new ArgumentNullException("lockObject");
            this.lockObject = lockObject;
            this.forWrite = forWrite;

            if (forWrite)
                lockObject.EnterWriteLock();
            else
                lockObject.EnterReadLock();
        }
コード例 #17
0
        public static LockHandle Read(this ReaderWriterLockSlim self)
        {
            Check.Self(self);

            if (self.IsReadLockHeld || self.IsUpgradeableReadLockHeld || self.IsWriteLockHeld)
            {
                return(new LockHandle());
            }

            self.EnterReadLock();
            return(new LockHandle(self, LockHandle.LockType.Read));
        }
コード例 #18
0
        public static void EnterExit()
        {
            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
            {
                Assert.False(rwls.IsReadLockHeld);
                rwls.EnterReadLock();
                Assert.True(rwls.IsReadLockHeld);
                rwls.ExitReadLock();
                Assert.False(rwls.IsReadLockHeld);

                Assert.False(rwls.IsUpgradeableReadLockHeld);
                rwls.EnterUpgradeableReadLock();
                Assert.True(rwls.IsUpgradeableReadLockHeld);
                rwls.ExitUpgradeableReadLock();
                Assert.False(rwls.IsUpgradeableReadLockHeld);

                Assert.False(rwls.IsWriteLockHeld);
                rwls.EnterWriteLock();
                Assert.True(rwls.IsWriteLockHeld);
                rwls.ExitWriteLock();
                Assert.False(rwls.IsWriteLockHeld);

                Assert.False(rwls.IsUpgradeableReadLockHeld);
                rwls.EnterUpgradeableReadLock();
                Assert.False(rwls.IsWriteLockHeld);
                Assert.True(rwls.IsUpgradeableReadLockHeld);
                rwls.EnterWriteLock();
                Assert.True(rwls.IsWriteLockHeld);
                rwls.ExitWriteLock();
                Assert.False(rwls.IsWriteLockHeld);
                Assert.True(rwls.IsUpgradeableReadLockHeld);
                rwls.ExitUpgradeableReadLock();
                Assert.False(rwls.IsUpgradeableReadLockHeld);

                Assert.True(rwls.TryEnterReadLock(0));
                rwls.ExitReadLock();

                Assert.True(rwls.TryEnterReadLock(Timeout.InfiniteTimeSpan));
                rwls.ExitReadLock();

                Assert.True(rwls.TryEnterUpgradeableReadLock(0));
                rwls.ExitUpgradeableReadLock();

                Assert.True(rwls.TryEnterUpgradeableReadLock(Timeout.InfiniteTimeSpan));
                rwls.ExitUpgradeableReadLock();

                Assert.True(rwls.TryEnterWriteLock(0));
                rwls.ExitWriteLock();

                Assert.True(rwls.TryEnterWriteLock(Timeout.InfiniteTimeSpan));
                rwls.ExitWriteLock();
            }
        }
コード例 #19
0
        /// <summary>
        /// Gets the elements.
        /// </summary>
        /// <returns></returns>
        public IQueryable <Element> GetElements()
        {
            locker.EnterReadLock();
            try
            {
                IEnumerable <Element> elements = Enumerable.Empty <Element>();
                if (Directory.Exists(path))
                {
                    string[] files = Directory.GetFiles(path);

                    for (int i = 0; i < files.Length; i++)
                    {
                        string fileName = files[i];
                        if (fileName.EndsWith(".resx"))
                        {
                            XDocument doc = XDocument.Load(files[i]);
                            string    culture;
                            string    category;
                            ResXResourceFileHelper.Parse(fileName, out culture, out category);

                            IEnumerable <Element> newElements = doc.Root.Elements("data")
                                                                .Select(x => new Element()
                            {
                                Category = category,
                                Culture  = culture,
                                Name     = x.Attribute("name").Value,
                                Value    = x.Element("value").Value
                            });

                            elements = elements.Union(newElements);
                        }
                    }
                }
                return(elements.AsQueryable <Element>());
            }
            finally
            {
                locker.ExitReadLock();
            }
        }
コード例 #20
0
		public void n3_multithreading()
		{
			int run = 1;
			int count = 1;
			const int max = 64;
			var exceptions = new List<Exception>();
			var locker = new ReaderWriterLockSlim();

			locker.EnterWriteLock();

			for (int i = 0; i < max; i++)
			{
				ThreadPool.QueueUserWorkItem((_) =>
				{
					Interlocked.Increment(ref count);
					locker.EnterReadLock();
					locker.ExitReadLock();

					try
					{
						while (Thread.VolatileRead(ref run) != 0)
						{
							DestroyReaders(
								CreateReaders(16), 0, false);
						}
					}
					catch (Exception ex)
					{
						exceptions.Add(ex);
					}

					Interlocked.Increment(ref count);
				});
			}

			while (Thread.VolatileRead(ref count) < max)
				Thread.Sleep(100);
			count = 1;
			locker.ExitWriteLock();


			Thread.Sleep(60000);
			run = 0;


			while (Thread.VolatileRead(ref count) < max)
				Thread.Sleep(1000);


			if (exceptions.Count > 0)
				throw exceptions[0];
		}
コード例 #21
0
        public bool TryGetValue(TKey1 key, out TValue value)
        {
            bool success;

            rwLock.EnterReadLock();

            try { success = Dictionary1.TryGetValue(key, out value); }
            finally { rwLock.ExitReadLock(); }

            return(success);
        }
コード例 #22
0
        public void OneManyLockIsFasterThanReaderWriterLockSlim()
        {
            // OneManyLock.
            var sw = Stopwatch.StartNew();
            using (var oml = new OneManyLock())
            {
                oml.Enter(true); 
                M(); 
                oml.Leave(true);
                for (Int32 i = 0; i < c_iterations; i++)
                {
                    oml.Enter(true); 
                    M();
                    oml.Leave(true);
                }
            }

            Int64 omlElapsedMilliseconds = sw.ElapsedMilliseconds;

            // ReaderWriterLockSlim.
            sw.Restart();
            using (var rwls = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion))
            {
                rwls.EnterReadLock();
                M();
                rwls.ExitReadLock();
                for (Int32 i = 0; i < c_iterations; i++)
                {
                    rwls.EnterReadLock();
                    M();
                    rwls.ExitReadLock();
                }
            }

            Int64 rwlsElapsedMilliseconds = sw.ElapsedMilliseconds;

            Assert.True(omlElapsedMilliseconds < rwlsElapsedMilliseconds);
        }
コード例 #23
0
ファイル: UnitTest1.cs プロジェクト: searbe/redis-client
        public void TestMethod2()
        {
            ISomething something = new Something();
            var tasks = new List<Task>();
            var rwlock = new ReaderWriterLockSlim();

            for (var i = 0; i < 100; i++)
            {
                // These threads should never see "nothing"....
                tasks.Add(Task.Run(() =>
                {
                    for (var x = 0; x < 1000000; x++)
                    {
                        rwlock.EnterReadLock();
                        try
                        {
                            Thread.Sleep(100);
                            Assert.That(something.IsNothing, Is.False);
                        }
                        finally
                        {
                            rwlock.ExitReadLock();
                        }
                    }
                }));
            }

            // ... even though this one keeps setting it to nothing
            tasks.Add(Task.Run(() =>
            {
                for (var x = 0; x < 1000000; x++)
                {
                    rwlock.EnterWriteLock();
                    try
                    {
                        something = new Nothing();
                        Thread.Sleep(100);
                        something = new Something();
                    }
                    finally
                    {
                        rwlock.ExitWriteLock();
                    }
                }
            }));

            Task.WhenAll(tasks).Wait();
        }
コード例 #24
0
ファイル: LockSlim.cs プロジェクト: glorylee/Aoite
 public LockExtend(ReaderWriterLockSlim slim, LockMode mode)
 {
     _Slim = slim;
     this._Mode = mode;
     switch(mode)
     {
         case LockMode.Write:
             slim.EnterWriteLock();
             break;
         case LockMode.Read:
             slim.EnterReadLock();
             break;
         case LockMode.UpgradeableRead:
             slim.EnterUpgradeableReadLock();
             break;
     }
 }
コード例 #25
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ReadLock"/> class.
        /// </summary>
        /// <param name="readerWriterLockSlim">The reader writer lock slim.</param>
        public NestableReadLock(ReaderWriterLockSlim readerWriterLockSlim)
        {
            // Keep track of the lock since we'll need it to release the lock.
            this.readerWriterLockSlim = readerWriterLockSlim;

            // If we already have a read or write lock, we don't do anything.
            if (readerWriterLockSlim.IsReadLockHeld
                || readerWriterLockSlim.IsUpgradeableReadLockHeld
                || readerWriterLockSlim.IsWriteLockHeld)
            {
                lockAcquired = false;
            }
            else
            {
                readerWriterLockSlim.EnterReadLock();
                lockAcquired = true;
            }
        }
コード例 #26
0
        public ScopedReaderWriterLock(ReaderWriterLockSlim readerWriterLock, bool readOnly = true)
        {
            if (_readerWriterLock == null)
            {
                throw new ArgumentNullException(nameof(readerWriterLock));
            }

            _readerWriterLock = readerWriterLock;
            _readOnly = readOnly;

            if (_readOnly)
            {
                _readerWriterLock.EnterReadLock();
            }
            else
            {
                _readerWriterLock.EnterWriteLock();
            }
        }
コード例 #27
0
        public bool IsWalkable(Point3 pos, bool isOversized)
        {
            _threadLock.EnterReadLock();
            bool val = false;

            if (_cells.TryGetValue(pos, out var cell))
            {
                val = cell.IsWalkable;
                if (isOversized && cell.IsEdge)
                {
                    val = false;
                }
            }
            _threadLock.ExitReadLock();
            return(val);
        }
コード例 #28
0
        public static void Dispose()
        {
            ReaderWriterLockSlim rwls;

            rwls = new ReaderWriterLockSlim();
            rwls.Dispose();
            Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterReadLock(0));
            Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterUpgradeableReadLock(0));
            Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterWriteLock(0));
            rwls.Dispose();

            for (int i = 0; i < 3; i++)
            {
                rwls = new ReaderWriterLockSlim();
                switch (i)
                {
                    case 0: rwls.EnterReadLock(); break;
                    case 1: rwls.EnterUpgradeableReadLock(); break;
                    case 2: rwls.EnterWriteLock(); break;
                }
                Assert.Throws<SynchronizationLockException>(() => rwls.Dispose());
            }
        }
コード例 #29
0
		public void EnterReadLock_MultiRead ()
		{
			var v = new ReaderWriterLockSlim ();
			int local = 10;

			var r = from i in Enumerable.Range (1, 30) select new Thread (() => {

				// Just to cause some contention
				Thread.Sleep (100);

				v.EnterReadLock ();

				Assert.AreEqual (10, local);
			});

			var threads = r.ToList ();

			foreach (var t in threads) {
				t.Start ();
			}

			foreach (var t in threads) {
				// Console.WriteLine (t.ThreadState);
				t.Join ();
			}
		}
コード例 #30
0
		public void EnterWriteLock_NoRecursionError ()
		{
			var v = new ReaderWriterLockSlim ();
			v.EnterWriteLock ();
			Assert.AreEqual (1, v.RecursiveWriteCount);

			try {
				v.EnterWriteLock ();
				Assert.Fail ("1");
			} catch (LockRecursionException) {
			}

			try {
				v.EnterReadLock ();
				Assert.Fail ("2");
			} catch (LockRecursionException) {
			}
		}
コード例 #31
0
		public void EnterUpgradeableReadLock ()
		{
			var v = new ReaderWriterLockSlim ();

			v.EnterUpgradeableReadLock ();
			Assert.IsTrue (v.IsUpgradeableReadLockHeld, "A");
			Assert.AreEqual (0, v.RecursiveWriteCount, "A1");
			Assert.AreEqual (0, v.RecursiveReadCount, "A2");
			Assert.AreEqual (1, v.RecursiveUpgradeCount, "A3");
			Assert.AreEqual (0, v.WaitingReadCount, "A4");
			Assert.AreEqual (0, v.WaitingUpgradeCount, "A5");
			Assert.AreEqual (0, v.WaitingWriteCount, "A6");
			v.ExitUpgradeableReadLock ();

			v.EnterUpgradeableReadLock ();
			Assert.IsTrue (v.IsUpgradeableReadLockHeld, "B");
			Assert.AreEqual (0, v.RecursiveWriteCount, "B1");
			Assert.AreEqual (0, v.RecursiveReadCount, "B2");
			Assert.AreEqual (1, v.RecursiveUpgradeCount, "B3");
			Assert.AreEqual (0, v.WaitingReadCount, "B4");
			Assert.AreEqual (0, v.WaitingUpgradeCount, "B5");
			Assert.AreEqual (0, v.WaitingWriteCount, "B6");

			v.EnterReadLock ();
			v.ExitUpgradeableReadLock ();

			Assert.IsTrue (v.IsReadLockHeld, "C");
			Assert.AreEqual (0, v.RecursiveWriteCount, "C1");
			Assert.AreEqual (1, v.RecursiveReadCount, "C2");
			Assert.AreEqual (0, v.RecursiveUpgradeCount, "C3");
			Assert.AreEqual (0, v.WaitingReadCount, "C4");
			Assert.AreEqual (0, v.WaitingUpgradeCount, "C5");
			Assert.AreEqual (0, v.WaitingWriteCount, "C6");

			v.ExitReadLock ();
		}
コード例 #32
0
    // 线程返回
    internal void _ThreadRun(bool doWait = true)
    {
        if (m_KdTree != null)
        {
            if (m_KdTreeStatus == KdTreeStatus.WaitRebuild)
            {
                m_KdTree.Rebuild();
                m_KdTreeStatus = KdTreeStatus.Rebuilded;

                m_ReadWriterLock.EnterWriteLock();
                m_VisibleQueueStatus = VisibleQueueStatus.WaitQuery;
                m_ReadWriterLock.ExitWriteLock();
            }
            else if (m_KdTreeStatus == KdTreeStatus.Rebuilded)
            {
                VisibleQueueStatus status = this.CurrentQueueStatus;

                if (status == VisibleQueueStatus.Refresh)
                {
                    if (m_LastVisibleHash != null)
                    {
                        m_LastVisibleHash.Clear();
                    }
                    status = VisibleQueueStatus.WaitQuery;
                }

                if (status == VisibleQueueStatus.WaitQuery)
                {
                    if (m_KdQuery == null)
                    {
                        m_KdQuery = new KDTree.KDQuery(100);
                    }
                    if (m_KdQueryIdxList == null)
                    {
                        m_KdQueryIdxList = new List <int> ();
                    }
                    else
                    {
                        m_KdQueryIdxList.Clear();
                    }

                    Vector3      center;
                    KdCameraInfo camInfo;
                    m_ReadWriterLock.EnterReadLock();
                    try {
                        camInfo = m_KdCamInfo;
                    } finally {
                        m_ReadWriterLock.ExitReadLock();
                    }
                    float radius = camInfo.far;
                    m_KdQuery.Radius(m_KdTree, camInfo.position, radius, m_KdQueryIdxList);

                    int visibleCount       = 0;
                    int kdTreeVisibleCount = m_KdQueryIdxList.Count;
                    m_TempHash.Clear();

                    if (m_KdQueryIdxList.Count > 0)
                    {
                        // 计算出摄影机面板
                                                #if _USE_WORLD_AXIS
                        KdCameraPanels camPanels = camInfo.CalcPanels();
                                                #else
                        Matrix4x4 mat       = camInfo.CalcViewProjMatrix();
                        Vector4   nearPlane = camInfo.nearPlane;
                                                #endif

                        for (int i = 0; i < m_KdQueryIdxList.Count; ++i)
                        {
                            int idx = m_KdQueryIdxList [i];
                            if (idx < 0 || idx >= m_KdTreeObjList.Count || idx >= m_VecArr.Length)
                            {
                                continue;
                            }

                            //Vector3 pos = m_VecArr [idx];
                            KdTreeObj obj = m_KdTreeObjList [idx];
                            //pos = camMVP.MultiplyPoint (pos);
                                                        #if _USE_WORLD_AXIS
                            bool isVisible = camInfo.IsBoundingSphereIn(obj.boundSphere, camPanels);
                                                        #else
                            bool isVisible = KdCameraInfo.IsBoundingSphereIn(obj.boundSphere, mat, nearPlane);                              //KdCameraInfo.NewPlane(camInfo.lookAt, camInfo.position)
                                                        #endif

                            // 摄影机剪裁
                            // 投递结果
                            if (isVisible)
                            {
                                ++visibleCount;

                                m_TempHash.Add(obj.InstanceId);
                            }
                        }
                    }

                    // 查看和上一帧变化的
                    VisibleNode chgRoot    = null;
                    VisibleNode chgEndNode = null;
                    if (m_TempHash.Count <= 0)
                    {
                        // 从有变到没有
                        if (m_LastVisibleHash != null)
                        {
                            var iter = m_LastVisibleHash.GetEnumerator();
                            while (iter.MoveNext())
                            {
                                var visibleNode = GetVisibleNode(iter.Current, false);
                                AddVisibleQueue(ref chgRoot, ref chgEndNode, visibleNode);
                            }
                            iter.Dispose();

                            m_LastVisibleHash.Clear();
                        }
                    }
                    else
                    {
                        if (m_LastVisibleHash == null)
                        {
                            m_LastVisibleHash = new HashSet <int> ();
                            var iter = m_TempHash.GetEnumerator();
                            while (iter.MoveNext())
                            {
                                var n = GetVisibleNode(iter.Current, true);
                                AddVisibleQueue(ref chgRoot, ref chgEndNode, n);
                            }
                            iter.Dispose();

                            var tmp = m_LastVisibleHash;
                            m_LastVisibleHash = m_TempHash;
                            m_TempHash        = tmp;
                        }
                        else
                        {
                            // rootNode下都是当前可见的
                            var iter = m_TempHash.GetEnumerator();
                            while (iter.MoveNext())
                            {
                                bool isContains = m_LastVisibleHash.Contains(iter.Current);
                                if (isContains)
                                {
                                    m_LastVisibleHash.Remove(iter.Current);
                                    continue;
                                }
                                var chgN = GetVisibleNode(iter.Current, true);
                                AddVisibleQueue(ref chgRoot, ref chgEndNode, chgN);
                            }
                            iter.Dispose();
                            // 剩下的就是从可见变成不可见
                            iter = m_LastVisibleHash.GetEnumerator();
                            while (iter.MoveNext())
                            {
                                var chgN = GetVisibleNode(iter.Current, false);
                                AddVisibleQueue(ref chgRoot, ref chgEndNode, chgN);
                            }
                            iter.Dispose();
                            // 交换一下
                            HashSet <int> tmp = m_LastVisibleHash;
                            m_LastVisibleHash = m_TempHash;
                            m_TempHash        = tmp;
                            m_TempHash.Clear();
                        }
                    }

                    VisibleNode tmpNode;


                    m_ReadWriterLock.EnterWriteLock();
                    try {
                        tmpNode              = m_ChgVisibleQueue;
                        m_VisibleCount       = visibleCount;
                        m_KdTreeVisible      = kdTreeVisibleCount;
                        m_ChgVisibleQueue    = chgRoot;
                        m_VisibleQueueStatus = VisibleQueueStatus.WaitChange;
                    } finally {
                        m_ReadWriterLock.ExitWriteLock();
                    }

                    if (tmpNode != null)
                    {
                        ClearVisibleQueue(ref tmpNode);
                    }
                }
                else
                {
                    doWait = false;
                }
            }

            if (doWait && _cThreadWait > 0)
            {
                System.Threading.Thread.Sleep(_cThreadWait);
            }
        }
    }
コード例 #33
0
        public void RecursiveWriteUpgradeReadTest()
        {
            var rwlock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

            rwlock.EnterWriteLock();
            Assert.IsTrue(rwlock.IsWriteLockHeld);
            rwlock.EnterUpgradeableReadLock();
            Assert.IsTrue(rwlock.IsUpgradeableReadLockHeld);
            rwlock.EnterReadLock();
            Assert.IsTrue(rwlock.IsReadLockHeld);
            rwlock.ExitUpgradeableReadLock();
            Assert.IsFalse(rwlock.IsUpgradeableReadLockHeld);
            Assert.IsTrue(rwlock.IsReadLockHeld);
            Assert.IsTrue(rwlock.IsWriteLockHeld);

            rwlock.ExitReadLock();
            Assert.IsTrue(rwlock.IsWriteLockHeld);
        }
コード例 #34
0
		public void RecursiveReadPlusUpgradeableLockTest ()
		{
			var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);

			try {
				v.EnterReadLock ();
				v.EnterUpgradeableReadLock ();
				Assert.Fail ("1");
			} catch (LockRecursionException ex) {
				Assert.IsNotNull (ex, "#1");
			}
		}
コード例 #35
0
        public static void DeadlockAvoidance()
        {
            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
            {
                rwls.EnterReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock());
                Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock());
                Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock());
                rwls.ExitReadLock();

                rwls.EnterUpgradeableReadLock();
                rwls.EnterReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock());
                rwls.ExitReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock());
                rwls.EnterWriteLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock());
                rwls.ExitWriteLock();
                rwls.ExitUpgradeableReadLock();

                rwls.EnterWriteLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock());
                Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock());
                Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock());
                rwls.ExitWriteLock();
            }

            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion))
            {
                rwls.EnterReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock());
                rwls.EnterReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock());
                rwls.ExitReadLock();
                rwls.ExitReadLock();

                rwls.EnterUpgradeableReadLock();
                rwls.EnterReadLock();
                rwls.EnterUpgradeableReadLock();
                rwls.ExitUpgradeableReadLock();
                rwls.EnterReadLock();
                rwls.ExitReadLock();
                rwls.ExitReadLock();
                rwls.EnterWriteLock();
                rwls.EnterWriteLock();
                rwls.ExitWriteLock();
                rwls.ExitWriteLock();
                rwls.ExitUpgradeableReadLock();

                rwls.EnterWriteLock();
                rwls.EnterReadLock();
                rwls.ExitReadLock();
                rwls.EnterUpgradeableReadLock();
                rwls.ExitUpgradeableReadLock();
                rwls.EnterWriteLock();
                rwls.ExitWriteLock();
                rwls.ExitWriteLock();
            }
        }
コード例 #36
0
        static void Main(string[] args)
        {
            rwls = new System.Threading.ReaderWriterLockSlim();
            DELG Read1 = (state) =>
            {
                string thread = (string)state;
                while (true)
                {
                    rwls.EnterReadLock();
                    try
                    {
                        Console.WriteLine("Thread -> {0} -- Message -> {1}", thread, val.ToString());
                    }
                    finally
                    {
                        rwls.ExitReadLock();
                    }
                    System.Threading.Thread.Sleep(2000);
                }
            };


            DELG Write1 = (state) =>
            {
                string thread = (string)state;
                int[]  tb     = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };
                for (int i = 0; i < 10; i++)
                {
                    rwls.EnterWriteLock();
                    try
                    {
                        val = tb[i];
                        Console.WriteLine("Changement de val par Thread -> {0}", thread);
                    }
                    finally
                    {
                        rwls.ExitWriteLock();
                    }
                    System.Threading.Thread.Sleep(3000);
                }
            };
            DELG Write2 = (state) =>
            {
                string thread = (string)state;
                int[]  tb     = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
                for (int i = 0; i < 10; i++)
                {
                    rwls.EnterWriteLock();
                    try
                    {
                        val = tb[i];
                        Console.WriteLine("Changement de val par Thread -> {0}", thread);
                    }
                    finally
                    {
                        rwls.ExitWriteLock();
                    }
                    System.Threading.Thread.Sleep(3000);
                }
            };

            System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Read1.Invoke));
            System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Read1.Invoke));
            System.Threading.Thread t3 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Write1.Invoke));
            System.Threading.Thread t4 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Write1.Invoke));
            t1.Start((object)("T1"));
            t2.Start((object)("T2"));
            t3.Start((object)("T3"));
            t4.Start((object)("T4"));
            Console.Read();
        }
コード例 #37
0
 public ReadLockToken(ReaderWriterLockSlim sync)
 {
     _sync = sync;
     sync.EnterReadLock();
 }
コード例 #38
0
        public static void ReleaseReadersWhenWaitingWriterTimesOut()
        {
            using (var rwls = new ReaderWriterLockSlim())
            {
                // Enter the read lock
                rwls.EnterReadLock();
                // Typical order of execution: 0

                Thread writeWaiterThread;
                using (var beforeTryEnterWriteLock = new ManualResetEvent(false))
                {
                    writeWaiterThread =
                        new Thread(() =>
                        {
                            // Typical order of execution: 1

                            // Add a writer to the wait list for enough time to allow successive readers to enter the wait list while this
                            // writer is waiting
                            beforeTryEnterWriteLock.Set();
                            if (rwls.TryEnterWriteLock(1000))
                            {
                                // The typical order of execution is not guaranteed, as sleep times are not guaranteed. For
                                // instance, before this write lock is added to the wait list, the two new read locks may be
                                // acquired. In that case, the test may complete before or while the write lock is taken.
                                rwls.ExitWriteLock();
                            }

                            // Typical order of execution: 4
                        });
                    writeWaiterThread.IsBackground = true;
                    writeWaiterThread.Start();
                    beforeTryEnterWriteLock.WaitOne();
                }
                Thread.Sleep(500); // wait for TryEnterWriteLock to enter the wait list

                // A writer should now be waiting, add readers to the wait list. Since a read lock is still acquired, the writer
                // should time out waiting, then these readers should enter and exit the lock.
                ThreadStart EnterAndExitReadLock = () =>
                {
                    // Typical order of execution: 2, 3
                    rwls.EnterReadLock();
                    // Typical order of execution: 5, 6
                    rwls.ExitReadLock();
                };
                var readerThreads =
                    new Thread[]
                    {
                        new Thread(EnterAndExitReadLock),
                        new Thread(EnterAndExitReadLock)
                    };
                foreach (var readerThread in readerThreads)
                {
                    readerThread.IsBackground = true;
                    readerThread.Start();
                }
                foreach (var readerThread in readerThreads)
                {
                    readerThread.Join();
                }

                rwls.ExitReadLock();
                // Typical order of execution: 7

                writeWaiterThread.Join();
            }
        }
コード例 #39
0
        /// <summary>
        /// Handles a quark crossing request. Checks to see if the request is possible, and returns true or false based on
        /// the validity of the crossing to the actor who requested. This is performed in 3 steps:
        /// Step 1: Tell root to be ready to receive crossing requests for the object
        /// Root will also do sanity checks (e.g. object was deleted before crossing), so checking actorStatus code
        /// is important.
        /// Step 2: Root provides URL for uploading updated properties and for downloading said object.
        /// Step 3: Tell actor about the URL where it may contact the root directly.
        /// TODO: This can be optimized if we are allowed to remember or calculate the URL. We could respond immediately with the URL
        /// and the actor would keep trying it until root accepts it. For now, we avoid concurrency.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actorRequest"></param>
        private void HandleCrossing(HttpListenerContext context, HttpListenerRequest actorRequest)
        {
            StreamReader    actorReader = new StreamReader(actorRequest.InputStream);
            XmlSerializer   deserializer = new XmlSerializer(typeof(CrossingRequest));
            CrossingRequest cross = (CrossingRequest)deserializer.Deserialize(actorReader);
            QuarkPublisher  curQp = null, prevQp = null;
            string          url = "";
            HttpStatusCode  status;

            m_crossLock.EnterReadLock();
            try
            {
                m_log.InfoFormat("{0}: Handling Crossing. Time: {1}", LogHeader, DateTime.Now.Ticks);
                if (m_quarkSubscriptions.TryGetValue(cross.curQuark, out curQp) && m_quarkSubscriptions.TryGetValue(cross.prevQuark, out prevQp))
                {
                    if (curQp.RootActorID != prevQp.RootActorID)
                    {
                        // TODO: Inter-root communication
                    }
                    else
                    {
                        // Actor's response variables
                        HttpListenerResponse actorResponse = context.Response;
                        Stream actorOutput = actorResponse.OutputStream;

                        // Root's request variables
                        RootInfo       root        = (RootInfo)m_actor[curQp.RootActorID];
                        HttpWebRequest rootRequest = (HttpWebRequest)WebRequest.Create("http://" + root.quarkAddress + "/cross/");
                        rootRequest.Credentials = CredentialCache.DefaultCredentials;
                        rootRequest.Method      = "POST";
                        rootRequest.ContentType = "text/json";
                        Stream rootOutput = rootRequest.GetRequestStream();

                        status = ValidateCrossing(cross);
                        if (status != HttpStatusCode.Created)
                        {
                            actorResponse.StatusCode = (int)status;
                            actorOutput.Close();
                            actorResponse.Close();
                            return;
                        }
                        // From here on, I might have to write, make sure we only do one of these at a time.
                        // Can't go in UpgradeableLock with a ReadLock, so let go first.
                        m_crossLock.ExitReadLock();
                        m_crossLock.EnterUpgradeableReadLock();
                        try
                        {
                            // First we double check nothing changed while we were waiting for the lock, and we are still valid to cross.
                            status = ValidateCrossing(cross);
                            if (status != HttpStatusCode.Created)
                            {
                                actorResponse.StatusCode = (int)status;
                                actorOutput.Close();
                                actorResponse.Close();
                                return;
                            }

                            // Step 1: Tell root to be ready to receive crossing requests for the object
                            // Root will also do sanity checks (e.g. object was deleted before crossing), so checking actorStatus code
                            // is important.
                            OSDMap DataMap = new OSDMap();
                            DataMap["uuid"] = OSD.FromUUID(cross.uuid);
                            DataMap["pq"]   = OSD.FromString(cross.prevQuark);
                            DataMap["cq"]   = OSD.FromString(cross.curQuark);
                            DataMap["ts"]   = OSD.FromLong(cross.timestamp);

                            string encodedMap     = OSDParser.SerializeJsonString(DataMap, true);
                            byte[] rootData       = System.Text.Encoding.ASCII.GetBytes(encodedMap);
                            int    rootDataLength = rootData.Length;
                            rootOutput.Write(rootData, 0, rootDataLength);
                            rootOutput.Close();

                            // Step 2: Root provides URL for uploading updated properties and for downloading said object.
                            HttpWebResponse response = (HttpWebResponse)rootRequest.GetResponse();
                            if (HttpStatusCode.OK == response.StatusCode)
                            {
                                m_crossLock.EnterWriteLock();
                                try
                                {
                                    m_crossings[cross.uuid]       = new CurrentCrossings();
                                    m_crossings[cross.uuid].cross = cross;
                                    m_crossings[cross.uuid].actors.UnionWith(m_quarkSubscriptions[cross.prevQuark].GetAllQuarkSubscribers());
                                    m_crossings[cross.uuid].actors.UnionWith(m_quarkSubscriptions[cross.curQuark].GetAllQuarkSubscribers());
                                    // Remove the starting actor from the list of actors to ACK.
                                    m_crossings[cross.uuid].actors.Remove(cross.actorID);
                                    m_crossings[cross.uuid].rootHandler = root;
                                }
                                finally
                                {
                                    m_crossLock.ExitWriteLock();
                                }
                                Stream       respData   = response.GetResponseStream();
                                StreamReader rootReader = new StreamReader(respData);
                                url = rootReader.ReadToEnd();
                                m_log.WarnFormat("{0}: Got URL for object request from server: {1}", LogHeader, url);
                                if (url.Length > 0)
                                {
                                    // Step 3: Tell actor about the URL where it may contact the root directly.
                                    // TODO: This can be optimized if we are allowed to remember or calculate the URL. We could respond immediately with the URL
                                    // and the actor would keep trying it until root accepts it. For now, we avoid concurrency.
                                    actorResponse.StatusCode = (int)HttpStatusCode.Created;
                                    byte[] actorUrlData       = System.Text.Encoding.ASCII.GetBytes(url);
                                    int    actorUrlDataLength = actorUrlData.Length;
                                    actorOutput.Write(actorUrlData, 0, actorUrlDataLength);
                                    actorOutput.Close();
                                    actorResponse.Close();
                                }
                                else
                                {
                                    m_log.ErrorFormat("{0}: Received empty URL from Root", LogHeader);
                                }
                            }
                            else
                            {
                                m_log.ErrorFormat("{0}: Failed to request crossing from root. Error Code: {1}", LogHeader, response.StatusCode);
                            }
                        }
                        finally
                        {
                            m_crossLock.ExitUpgradeableReadLock();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("{0}: Failed to request crossing from root and forward to actor. Exception: {1}\n{2}", LogHeader, e, e.StackTrace);
            }
            finally
            {
                if (m_crossLock.IsReadLockHeld)
                {
                    m_crossLock.ExitReadLock();
                }
            }
        }
コード例 #40
0
 public static void WriterToReaderChain()
 {
     using (AutoResetEvent are = new AutoResetEvent(false))
     using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
     {
         rwls.EnterWriteLock();
         Task t = Task.Factory.StartNew(() =>
         {
             Assert.False(rwls.TryEnterReadLock(TimeSpan.FromMilliseconds(10)));
             Task.Run(() => are.Set()); // ideally this won't fire until we've called EnterReadLock, but it's a benign race in that the test will succeed either way
             rwls.EnterReadLock();
             rwls.ExitReadLock();
         }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
         are.WaitOne();
         rwls.ExitWriteLock();
         t.GetAwaiter().GetResult();
     }
 }
コード例 #41
0
 public static void ReadersMayBeConcurrent()
 {
     using (Barrier barrier = new Barrier(2))
     using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
     {
         Assert.Equal(0, rwls.CurrentReadCount);
         Task.WaitAll(
             Task.Run(() =>
             {
                 rwls.EnterReadLock();
                 barrier.SignalAndWait(); // 1
                 Assert.True(rwls.IsReadLockHeld);
                 barrier.SignalAndWait(); // 2
                 Assert.Equal(2, rwls.CurrentReadCount);
                 barrier.SignalAndWait(); // 3
                 barrier.SignalAndWait(); // 4
                 rwls.ExitReadLock();
             }),
             Task.Run(() =>
             {
                 barrier.SignalAndWait(); // 1
                 rwls.EnterReadLock();
                 barrier.SignalAndWait(); // 2
                 Assert.True(rwls.IsReadLockHeld);
                 Assert.Equal(0, rwls.WaitingReadCount);
                 barrier.SignalAndWait(); // 3
                 rwls.ExitReadLock();
                 barrier.SignalAndWait(); // 4
             }));
         Assert.Equal(0, rwls.CurrentReadCount);
     }
 }
コード例 #42
0
        public static void InvalidExits(LockRecursionPolicy policy)
        {
            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(policy))
            {
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock());

                rwls.EnterReadLock();
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock());
                rwls.ExitReadLock();

                rwls.EnterUpgradeableReadLock();
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock());
                rwls.ExitUpgradeableReadLock();

                rwls.EnterWriteLock();
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock());
                rwls.ExitWriteLock();

                using (Barrier barrier = new Barrier(2))
                {
                    Task t = Task.Factory.StartNew(() =>
                    {
                        rwls.EnterWriteLock();
                        barrier.SignalAndWait();
                        barrier.SignalAndWait();
                        rwls.ExitWriteLock();
                    }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);

                    barrier.SignalAndWait();
                    Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock());
                    barrier.SignalAndWait();

                    t.GetAwaiter().GetResult();
                }
            }
        }
コード例 #43
0
		public void TryEnterWriteLock_WhileReading ()
		{
			var v = new ReaderWriterLockSlim ();
			AutoResetEvent ev = new AutoResetEvent (false);
			AutoResetEvent ev2 = new AutoResetEvent (false);

			Thread t1 = new Thread (() => {
				v.EnterReadLock ();
				ev2.Set ();
				ev.WaitOne ();
				v.ExitReadLock ();
			});

			t1.Start ();
			ev2.WaitOne ();

			Assert.IsFalse (v.TryEnterWriteLock (100));
			Assert.IsFalse (v.TryEnterReadLock (100));
			ev.Set ();

			Assert.IsTrue (v.TryEnterWriteLock (100));
		}
コード例 #44
0
        public void EnterWriteLock_MultiRead()
        {
            var v = new ReaderWriterLockSlim();
            int local = 10;
            int ready_count = 0;
            int entered_count = 0;
            const int thread_count = 10;

            var r = from i in Enumerable.Range(1, thread_count)
                    select new Thread(() =>
            {
                Interlocked.Increment(ref ready_count);
                v.EnterReadLock();
                Interlocked.Increment(ref entered_count);

                Assert.AreEqual(11, local);
            });

            v.EnterWriteLock();

            var threads = r.ToList();
            foreach (var t in threads)
            {
                t.Start();
            }

            while (ready_count != thread_count)
                Thread.Sleep(10);

            /* Extra up to 2s of sleep to ensure all threads got the chance to enter the lock */
            for (int i = 0; i < 200 && v.WaitingReadCount != thread_count; ++i)
                Thread.Sleep(10);
            local = 11;

            Assert.AreEqual(0, v.WaitingWriteCount, "in waiting write");
            Assert.AreEqual(thread_count, v.WaitingReadCount, "in waiting read");
            Assert.AreEqual(0, v.WaitingUpgradeCount, "in waiting upgrade");
            v.ExitWriteLock();

            foreach (var t in threads)
            {
                // Console.WriteLine (t.ThreadState);
                t.Join();
            }
        }
コード例 #45
0
		public void EnterWriteLock_MultiRead ()
		{
			var v = new ReaderWriterLockSlim ();
			int local = 10;

			var r = from i in Enumerable.Range (1, 10) select new Thread (() => {
				v.EnterReadLock ();

				Assert.AreEqual (11, local);
			});

			v.EnterWriteLock ();

			var threads = r.ToList ();
			foreach (var t in threads) {
				t.Start ();
			}

			Thread.Sleep (200);
			local = 11;

			// FIXME: Don't rely on Thread.Sleep (200)
			Assert.AreEqual (0, v.WaitingWriteCount, "in waiting write");
			Assert.AreEqual (10, v.WaitingReadCount, "in waiting read");
			Assert.AreEqual (0, v.WaitingUpgradeCount, "in waiting upgrade");
			v.ExitWriteLock ();

			foreach (var t in threads) {
				// Console.WriteLine (t.ThreadState);
				t.Join ();
			}
		}
コード例 #46
0
        public void RecursiveEnterExitReadTest()
        {
            var v = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

            v.EnterReadLock();
            v.EnterReadLock();
            v.EnterReadLock();

            Assert.IsTrue(v.IsReadLockHeld);
            Assert.AreEqual(3, v.RecursiveReadCount);

            v.ExitReadLock();

            Assert.IsTrue(v.IsReadLockHeld);
            Assert.AreEqual(2, v.RecursiveReadCount);
        }
コード例 #47
0
		public void RecursiveReadPropertiesTest ()
		{
			var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);

			v.EnterReadLock ();
			v.EnterReadLock ();

			Assert.AreEqual (true, v.IsReadLockHeld, "#1a");
			Assert.AreEqual (1, v.CurrentReadCount, "#2a");
			Assert.AreEqual (2, v.RecursiveReadCount, "#3a");

			bool rLock = true;
			int cReadCount = -1, rReadCount = -1;

			Thread t = new Thread ((_) => {
					rLock = v.IsReadLockHeld;
					cReadCount = v.CurrentReadCount;
					rReadCount = v.RecursiveReadCount;
				});

			t.Start ();
			t.Join ();

			Assert.AreEqual (false, rLock, "#1b");
			Assert.AreEqual (1, cReadCount, "#2b");
			Assert.AreEqual (0, rReadCount, "#3b");
		}
コード例 #48
0
 public ReadLockToken(ReaderWriterLockSlim @lock)
 {
     this._lock = @lock;
     @lock.EnterReadLock();
 }
コード例 #49
0
        // TypeCast_Overloads
        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator to iterate through the collection
        /// </summary>
        public IEnumerator GetEnumerator()
        {
            // http://www.csharphelp.com/archives/archive181.html

            List <T> localList;

            // init enumerator
            LockList.EnterReadLock();
            try
            {
                // create a copy of m_TList
                localList = new List <T>(m_TList);
            }
            finally
            {
                LockList.ExitReadLock();
            }

            // get the enumerator
            foreach (T item in localList)
            {
                yield return(item);
            }
        }
コード例 #50
0
        public static void DontReleaseWaitingReadersWhenThereAreWaitingWriters()
        {
            using(var rwls = new ReaderWriterLockSlim())
            {
                rwls.EnterUpgradeableReadLock();
                rwls.EnterWriteLock();
                // Typical order of execution: 0

                // Add a waiting writer
                var threads = new Thread[2];
                using(var beforeEnterWriteLock = new ManualResetEvent(false))
                {
                    var thread =
                        new Thread(() =>
                        {
                            beforeEnterWriteLock.Set();
                            rwls.EnterWriteLock();
                            // Typical order of execution: 3
                            rwls.ExitWriteLock();
                        });
                    thread.IsBackground = true;
                    thread.Start();
                    threads[0] = thread;
                    beforeEnterWriteLock.WaitOne();
                }

                // Add a waiting reader
                using(var beforeEnterReadLock = new ManualResetEvent(false))
                {
                    var thread =
                        new Thread(() =>
                        {
                            beforeEnterReadLock.Set();
                            rwls.EnterReadLock();
                            // Typical order of execution: 4
                            rwls.ExitReadLock();
                        });
                    thread.IsBackground = true;
                    thread.Start();
                    threads[1] = thread;
                    beforeEnterReadLock.WaitOne();
                }

                // Wait for the background threads to block waiting for their locks
                Thread.Sleep(1000);

                // Typical order of execution: 1
                rwls.ExitWriteLock();
                // At this point there is still one reader and one waiting writer, so the reader-writer lock should not try to
                // release any of the threads waiting for a lock

                // Typical order of execution: 2
                rwls.ExitUpgradeableReadLock();
                // At this point, the waiting writer should be released, and the waiting reader should not

                foreach(var thread in threads)
                    thread.Join();
                // Typical order of execution: 5
            }
        }