ExitReadLock() public method

public ExitReadLock ( ) : void
return void
Example #1
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(); }
 }
Example #2
0
 public Cache.Group this[string name, UUID UUID]
 {
     get
     {
         Cache.Group group;
         SyncRoot.EnterReadLock();
         nameUUIDHandleCache.TryGetValue(name, UUID, out group);
         SyncRoot.ExitReadLock();
         return(group);
     }
 }
Example #3
0
 public Cache.Region this[string name]
 {
     get
     {
         Cache.Region region;
         SyncRoot.EnterReadLock();
         nameCache.TryGetValue(name, out region);
         SyncRoot.ExitReadLock();
         return(region);
     }
 }
Example #4
0
        public IEnumerator <T> GetEnumerator()
        {
            locker.EnterReadLock();

            var tempFront = ((_front - 1) % _capacity).ToMinInt(0);
            var tempRear  = _rear;

            if (_count > 0)
            {
                do
                {
                    yield return(valueList[tempFront]);

                    tempFront = (tempFront + 1) % _capacity;
                } while (tempFront != tempRear);
                //while (tempFront != tempRear)
                //{

                //}
            }



            locker.ExitReadLock();
        }
Example #5
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);
        }
Example #6
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();
            }
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
        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();
                }
            }
        }
Example #10
0
 public WriteLock(ReaderWriterLockSlim rwLock)
     : base(rwLock)
 {
     if (rwLock.IsReadLockHeld)
     {
         rwLock.ExitReadLock();
         _downGradeLockOnExit = true;
     }
     Lock.EnterWriteLock();
 }
        public void EntersReadLock()
        {
            var slim = new ReaderWriterLockSlim();

            var token = slim.Read();

            Assert.IsTrue(slim.IsReadLockHeld);
            slim.ExitReadLock();

            slim.Dispose();
        }
        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();
            }
        }
        /// <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();
            }
        }
		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];
		}
        public bool TryGetValue(TKey1 key, out TValue value)
        {
            bool success;

            rwLock.EnterReadLock();

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

            return(success);
        }
        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);
        }
Example #17
0
        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();
        }
Example #18
0
 public Cache.Agent this[string firstname, string lastname]
 {
     get
     {
         Cache.Agent agent;
         SyncRoot.EnterReadLock();
         nameHandleCache.TryGetValue(firstname, lastname, out agent);
         SyncRoot.ExitReadLock();
         return(agent);
     }
 }
Example #19
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);
        }
            public void Dispose()
            {
                ReaderWriterLockSlim copy = Interlocked.Exchange(ref rwlock, null);

                if (copy == null)
                {
                    return;
                }

                switch (type)
                {
                case LockType.Read:
                    copy.ExitReadLock();
                    break;

                case LockType.UpgradeableRead:
                    copy.ExitUpgradeableReadLock();
                    break;

                case LockType.Write:
                    copy.ExitWriteLock();
                    break;
                }
            }
 private void ExitWriteLock(ReaderWriterLockSlim detectorLock)
 {
     detectorLock.ExitWriteLock();
     detectorLock.EnterReadLock();
     detectorLock.ExitUpgradeableReadLock();
     detectorLock.ExitReadLock();
 }
 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);
     }
 }
Example #23
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));
		}
        /// <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();
                }
            }
        }
        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);
        }
Example #26
0
		public void ExitReadLock ()
		{
			var v = new ReaderWriterLockSlim ();
			v.ExitReadLock ();
		}
Example #27
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();
        }
        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
            }
        }
Example #29
0
        private void Foo4()
        {
            var concurentDictionary = new Dictionary<int, int>();
            var rwLockSlim = new ReaderWriterLockSlim();

            var w = new ManualResetEvent(false);
            int timedCalled = 0;
            var threads = new List<Thread>();
            int j;
            Lazy<int> lazy = new Lazy<int>(() => { Interlocked.Increment(ref timedCalled); return 1; });
            for (int i = 0; i < Environment.ProcessorCount; i++)
            {
                threads.Add(new Thread(() =>
                {
                    w.WaitOne();
                    bool exist = false;
                    rwLockSlim.EnterReadLock();
                    try
                    {
                        exist = concurentDictionary.TryGetValue(1, out j);
                    }
                    finally
                    {
                        rwLockSlim.ExitReadLock();
                    }

                    if (!exist)
                    {
                        rwLockSlim.EnterUpgradeableReadLock();
                        try
                        {
                            if (!concurentDictionary.TryGetValue(1, out j))
                            {
                                rwLockSlim.EnterWriteLock();
                                try
                                {
                                    Interlocked.Increment(ref timedCalled);
                                    concurentDictionary[1] = 1;
                                }
                                finally
                                {
                                    rwLockSlim.ExitWriteLock();
                                }
                            }
                        }
                        finally
                        {
                            rwLockSlim.ExitUpgradeableReadLock();

                        }

                    }

                }));

                threads.Last().Start();
            }

            w.Set();//release all threads to start at the same time
            Thread.Sleep(100);
            Console.WriteLine(timedCalled);// output is 1
        }
        public void Start()
        {
            //ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
            //ParameterizedThreadStart reader = o =>
            //{
            //    var innerlocker = locker;
            //    int number = Convert.ToInt32(o);
            //    for (int i = 0; i < 10; i++)
            //    {
            //        //进入读状态 那么下面的 thread2将会暂停运行

            //        locker.EnterReadLock();
            //        Console.WriteLine("Reading  " + i);
            //        Thread.Sleep(5000);
            //        //退出读状态 下面的thread2将会继续运行
            //        locker.ExitReadLock();
            //    }
            //};

            //ParameterizedThreadStart writer = o =>
            //{
            //    var innerlocker = locker;
            //    for (int i = 11; i < 200; i++)
            //    {
            //        //进入写状态 上面的线程thread1将会暂停运行
            //        Thread.Sleep(50);//睡一下 给上面的线程 执行锁定 locker.EnterReadLock();
            //        locker.EnterWriteLock();
            //        Console.WriteLine("Writing  " + i);
            //        //退出写状态 上面的线程thread1将会继续运行
            //        Thread.Sleep(500);
            //        locker.ExitWriteLock();
            //    }

            //};

            //Thread thread1 = new Thread(reader);
            //thread1.Start();

            //Thread thread2 = new Thread(writer);
            //thread2.Start();

            ReaderWriterLockSlim locker = new ReaderWriterLockSlim();

            new Thread(new ParameterizedThreadStart(delegate
            {
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(1);
                    locker.EnterWriteLock();
                    Thread.Sleep(50);
                    list.Add("t1-" + i);
                    locker.ExitWriteLock();
                }
            })).Start();

            new Thread(new ParameterizedThreadStart(delegate
            {
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(1);
                    locker.EnterReadLock();

                    //locker.EnterWriteLock();
                    Thread.Sleep(50);
                    list.Add("t2-" + i);

                    //locker.ExitWriteLock();
                    locker.ExitReadLock();
                }
            })).Start();

            Thread.Sleep(20000);//20秒后输出结果
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

            //总结 只要使用了同一个锁 那么 只要锁进入了任何一个状态 例如 EnterWriteLock 那么EnterReadLock 或者另外一个EnterWriteLock 所在的线程将会暂停运行 反之一样
            Console.ReadLine();
        }
Example #31
0
 private static void FreeReaderLock(ReaderWriterLockSlim oLock)
 {
     oLock.ExitReadLock();
 }
Example #32
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);
            }
        }
        static void Main(string[] args) {

            // create the reader-writer lock
            ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim();

            // create a cancellation token source
            CancellationTokenSource tokenSource = new CancellationTokenSource();

            // create an array of tasks
            Task[] tasks = new Task[5];

            for (int i = 0; i < 5; i++) {
                // create a new task
                tasks[i] = new Task(() => {
                    while (true) {
                        // acqure the read lock
                        rwlock.EnterReadLock();
                        // we now have the lock
                        Console.WriteLine("Read lock acquired - count: {0}",
                            rwlock.CurrentReadCount);
                        // wait - this simulates a read operation
                        tokenSource.Token.WaitHandle.WaitOne(1000);
                        // release the read lock
                        rwlock.ExitReadLock();
                        Console.WriteLine("Read lock released - count {0}",
                            rwlock.CurrentReadCount);
                        // check for cancellation
                        tokenSource.Token.ThrowIfCancellationRequested();
                    }
                }, tokenSource.Token);
                // start the new task
                tasks[i].Start();
            }

            // prompt the user
            Console.WriteLine("Press enter to acquire write lock");
            // wait for the user to press enter 
            Console.ReadLine();

            // acquire the write lock
            Console.WriteLine("Requesting write lock");
            rwlock.EnterWriteLock();

            Console.WriteLine("Write lock acquired");
            Console.WriteLine("Press enter to release write lock");
            // wait for the user to press enter 
            Console.ReadLine();
            // release the write lock
            rwlock.ExitWriteLock();

            // wait for 2 seconds and then cancel the tasks
            tokenSource.Token.WaitHandle.WaitOne(2000);
            tokenSource.Cancel();

            try {
                // wait for the tasks to complete
                Task.WaitAll(tasks);
            } catch (AggregateException) {
                // do nothing
            }

            // wait for input before exiting
            Console.WriteLine("Press enter to finish");
            Console.ReadLine();
        }
 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();
     }
 }
Example #35
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);
            }
        }
    }
        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();
            }
        }
		public void ReaderWriterLockUsage()
		{
			// для секций с известной операцией доступа (чтение или запись) можно использовать
			// ReaderWriterLockSlim (ReaderWriterLock не рекомендуется)
			ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();

			rwLock.EnterReadLock();
			// критическая секция с чтением данных
			rwLock.ExitReadLock();

			rwLock.EnterWriteLock();
			// критическая секция с изменением данных
			rwLock.ExitWriteLock();

			// также существует класс ConcurrentExclusiveSchedulerPair,
			// который содержит 2 менеджера заданий
			// все задания в ExclusiveScheduler выполняются по одному, 
			// если не выполняется ни одно задание в ConcurrentScheduler
			// все задания в ConcurrentScheduler выполняются одновременно, 
			// если не выполняется ни одно задание в ExclusiveScheduler
			ConcurrentExclusiveSchedulerPair schedulerPair = new ConcurrentExclusiveSchedulerPair();
			TaskFactory exclusiveFactory = new TaskFactory(schedulerPair.ExclusiveScheduler);
			exclusiveFactory.StartNew(() => Console.WriteLine(DateTime.Now.ToLongTimeString()));

			// класс, который блокирует поток, пока внутренний счётчик не достигнет нуля
			CountdownEvent countdownEvent = new CountdownEvent(5);
			countdownEvent.Wait();
			// критическая секция
			countdownEvent.Signal(2); // блокировка не снята
			countdownEvent.Signal(3); // блокировка снята

			// класс Barrier предоставляет возможность совокупности потоков проходить
			// через определённые шаги исполнения одновременно
		}
 protected override void ExitLock(ReaderWriterLockSlim readerWriterLockSlim)
 {
     readerWriterLockSlim.ExitReadLock();
 }
        private void Exit( bool reEnterWriteLock, ReaderWriterLockSlim @lock )
        {
            if ( reEnterWriteLock )
            {
                if ( this.UseDeadlockDetection )
                {
                    MethodInterceptionArgs args = new MethodInterceptionArgsImpl( @lock, Arguments.Empty ) { TypedBinding = WriterReadLockBinding.Instance };

                    DeadlockDetectionPolicy.ReaderWriterEnhancements.Instance.OnWriterLockEnter( args );
                }
                else
                {
                    @lock.EnterWriteLock();
                }
            }
            else
            {
                if ( this.UseDeadlockDetection )
                {
                    MethodExecutionArgs args = new MethodExecutionArgs( @lock, Arguments.Empty );

                    DeadlockDetectionPolicy.ReaderWriterEnhancements.Instance.OnReaderLockExit( args );
                }

                @lock.ExitReadLock();
            }
        }
        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);
        }
        static void Main(string[] args) {

            // create the reader-writer lock
            ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim();

            // create a cancellation token source
            CancellationTokenSource tokenSource = new CancellationTokenSource();

            // create some shared data
            int sharedData = 0;

            // create an array of tasks
            Task[] readerTasks = new Task[5];

            for (int i = 0; i < readerTasks.Length; i++) {
                // create a new task
                readerTasks[i] = new Task(() => {
                    while (true) {
                        // acqure the read lock
                        rwlock.EnterReadLock();
                        // we now have the lock
                        Console.WriteLine("Read lock acquired - count: {0}",
                            rwlock.CurrentReadCount);

                        // read the shared data
                        Console.WriteLine("Shared data value {0}", sharedData);

                        // wait - slow things down to make the example clear
                        tokenSource.Token.WaitHandle.WaitOne(1000);

                        // release the read lock
                        rwlock.ExitReadLock();
                        Console.WriteLine("Read lock released - count {0}",
                            rwlock.CurrentReadCount);

                        // check for cancellation
                        tokenSource.Token.ThrowIfCancellationRequested();
                    }
                }, tokenSource.Token);
                // start the new task
                readerTasks[i].Start();
            }

            Task[] writerTasks = new Task[2];
            for (int i = 0; i < writerTasks.Length; i++) {
                writerTasks[i] = new Task(() => {
                    while (true) {
                        // acquire the upgradeable lock
                        rwlock.EnterUpgradeableReadLock();

                        // simulate a branch that will require a write 
                        if (true) {
                            // acquire the write lock
                            rwlock.EnterWriteLock();
                            // print out a message with the details of the lock
                            Console.WriteLine("Write Lock acquired - waiting readers {0}, writers {1}, upgraders {2}",
                                rwlock.WaitingReadCount, rwlock.WaitingWriteCount,
                                rwlock.WaitingUpgradeCount);

                            // modify the shared data
                            sharedData++;

                            // wait - slow down the example to make things clear
                            tokenSource.Token.WaitHandle.WaitOne(1000);
                            // release the write lock
                            rwlock.ExitWriteLock();
                        }

                        // release the upgradable lock
                        rwlock.ExitUpgradeableReadLock();

                        // check for cancellation
                        tokenSource.Token.ThrowIfCancellationRequested();
                    }
                    
                }, tokenSource.Token);
                // start the new task
                writerTasks[i].Start();
            }

            // prompt the user
            Console.WriteLine("Press enter to cancel tasks");
            // wait for the user to press enter 
            Console.ReadLine();

            // cancel the tasks
            tokenSource.Cancel();

            try {
                // wait for the tasks to complete
                Task.WaitAll(readerTasks);
            } catch (AggregateException agex) {
                agex.Handle(ex => true);
            }

            // wait for input before exiting
            Console.WriteLine("Press enter to finish");
            Console.ReadLine();
        }
Example #42
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 ();
		}
        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();
            }
        }
Example #44
0
		public void RecursiveWritePlusReadLockTest ()
		{
			var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);

			Assert.IsTrue (v.TryEnterWriteLock (100), "#1");
			Assert.AreEqual (1, v.RecursiveWriteCount, "1b");
			Assert.AreEqual (0, v.RecursiveReadCount, "1c");

			Assert.IsTrue (v.TryEnterReadLock (100), "#2");
			Assert.AreEqual (1, v.RecursiveWriteCount, "2b");
			Assert.AreEqual (1, v.RecursiveReadCount, "2c");

			Assert.IsTrue (v.TryEnterReadLock (100), "#3");
			Assert.AreEqual (1, v.RecursiveWriteCount, "3b");
			Assert.AreEqual (2, v.RecursiveReadCount, "3c");

			v.ExitReadLock ();
			Assert.AreEqual (1, v.RecursiveWriteCount, "4b");
			Assert.AreEqual (1, v.RecursiveReadCount, "4c");
		}
        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();
                }
            }
        }
 public static void ReleaseReadOnlyLock(ReaderWriterLockSlim locks)
 {
     if (locks.IsReadLockHeld)
         locks.ExitReadLock();
 }
        /// <summary>
        /// Lock our inventory list for reading (many can read, one can write)
        /// </summary>
        public void LockItemsForRead(bool locked)
        {
            if (locked)
            {
                if (m_itemLock.IsWriteLockHeld && LockedByThread != null)
                {
                    if (!LockedByThread.IsAlive)
                    {
                        //Locked by dead thread, reset.
                        m_itemLock = new System.Threading.ReaderWriterLockSlim();
                    }
                }

                if (m_itemLock.RecursiveReadCount > 0)
                {
                    m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
                    try
                    {
                        // That call stack is useful for end users only. RealProgrammers need a full dump. Commented.
                        // StackTrace stackTrace = new StackTrace();           // get call stack
                        // StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)
                        //
                        // // write call stack method names
                        // foreach (StackFrame stackFrame in stackFrames)
                        // {
                        //     m_log.Error("[SceneObjectGroup.m_parts]  "+(stackFrame.GetMethod().Name));   // write method name
                        // }

                        // The below is far more useful
                        //                        System.Console.WriteLine("------------------------------------------");
                        //                        System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
                        //                        System.Console.WriteLine("------------------------------------------");
                        //                        foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
                        //                        {
                        //                            System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
                        //                            System.Console.WriteLine("------------------------------------------");
                        //                        }
                    }
                    catch
                    { }
                    m_itemLock.ExitReadLock();
                }
                if (m_itemLock.RecursiveWriteCount > 0)
                {
                    m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
                    //                    try
                    //                    {
                    //                        System.Console.WriteLine("------------------------------------------");
                    //                        System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
                    //                        System.Console.WriteLine("------------------------------------------");
                    //                        System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
                    //                        System.Console.WriteLine("------------------------------------------");
                    //                    }
                    //                    catch
                    //                    {}
                    m_itemLock.ExitWriteLock();
                }

                while (!m_itemLock.TryEnterReadLock(60000))
                {
                    m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
                    //if (m_itemLock.IsWriteLockHeld)
                    //{
                    m_itemLock = new System.Threading.ReaderWriterLockSlim();
                    //                        System.Console.WriteLine("------------------------------------------");
                    //                        System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
                    //                        System.Console.WriteLine("------------------------------------------");
                    //                        System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
                    //                        System.Console.WriteLine("------------------------------------------");
                    //                        LockedByThread = null;
                    //                        ReadLockers.Clear();
                    //}
                }
                //                ReadLockers[Thread.CurrentThread] = Environment.StackTrace;
            }
            else
            {
                if (m_itemLock.RecursiveReadCount > 0)
                {
                    m_itemLock.ExitReadLock();
                }
                //                if (m_itemLock.RecursiveReadCount == 0)
                //                    ReadLockers.Remove(Thread.CurrentThread);
            }
        }