示例#1
0
        public void WaitDoesNotThrowTheSecondTimeForAGivenThread()
        {
            var l = new TrackedLock(Locks, "A");

            l.BlockingEnter();

            var exc = new Exception[1];

            var secondTimeSignal = new AutoResetEvent(false);
            var waiterThread     = new Thread(
                () => {
                try {
                    l.BlockingEnter();
                    l.Exit();

                    secondTimeSignal.WaitOne();

                    l.BlockingEnter();
                    l.Exit();
                } catch (Exception e) {
                    exc[0] = e;
                }
            }
                );

            waiterThread.Priority = ThreadPriority.Highest;
            waiterThread.Start();

            while (
                (l.WaitingThreadCount == 0) &&
                (waiterThread.ThreadState != ThreadState.Stopped) &&
                (waiterThread.ThreadState != ThreadState.Aborted)
                )
            {
                Thread.Sleep(1);
            }

            l.Exit();
            l.BlockingEnter();

            secondTimeSignal.Set();

            while (
                (l.WaitingThreadCount == 0) &&
                (waiterThread.ThreadState != ThreadState.Stopped) &&
                (waiterThread.ThreadState != ThreadState.Aborted)
                )
            {
                Thread.Sleep(1);
            }

            l.Exit();

            waiterThread.Join();

            if (exc[0] != null)
            {
                throw new Exception("Worker thread failed", exc[0]);
            }
        }
示例#2
0
        public void WaitThrowsIfSimpleDeadlockWouldHaveOccurred()
        {
            var lA = new TrackedLock(Locks, "A");
            var lB = new TrackedLock(Locks, "B");

            lA.BlockingEnter();

            var threadStartedSignal = new AutoResetEvent(false);
            var bOwnerThread        = new Thread(
                () => {
                lB.BlockingEnter();
                threadStartedSignal.Set();
                lA.BlockingEnter();
            }
                );

            bOwnerThread.Priority = ThreadPriority.Highest;
            bOwnerThread.Name     = "B Owner";
            bOwnerThread.Start();

            threadStartedSignal.WaitOne();
            while (lA.WaitingThreadCount == 0)
            {
                Thread.Sleep(1);
            }

            Assert.Throws <DeadlockAvertedException>(() => lB.BlockingEnter());

            lA.Exit();

            bOwnerThread.Join();
        }
示例#3
0
        public void WaitThrowsIfAlreadyHeld()
        {
            var l = new TrackedLock(Locks, "A");

            l.BlockingEnter();

            Assert.Throws <LockAlreadyHeldException>(() => l.BlockingEnter());

            l.Exit();
        }
示例#4
0
        public void WaitBlocksUntilReleased()
        {
            var log = new List <string>();
            var l   = new TrackedLock(Locks, "A");

            lock (log)
                log.Add("Main+TryEnter");
            Assert.IsTrue(l.TryEnter().Success);
            lock (log)
                log.Add("Main-TryEnter");

            var threadStartedSignal = new AutoResetEvent(false);
            var waiterThread        = new Thread(
                () => {
                threadStartedSignal.Set();
                lock (log)
                    log.Add("Waiter+Enter");
                l.BlockingEnter();
                lock (log)
                    log.Add("Waiter-Enter");
                l.Exit();
            }
                );

            waiterThread.Priority = ThreadPriority.Highest;
            waiterThread.Name     = "Waiter";
            waiterThread.Start();

            threadStartedSignal.WaitOne();

            // FIXME: There's a race here since WaitingThreadCount actually increases
            //  slightly before the thread begins waiting. Bleh.
            while (l.WaitingThreadCount == 0)
            {
                Thread.Sleep(1);
            }

            lock (log)
                log.Add("Main+Exit");
            l.Exit();
            lock (log)
                log.Add("Main-Exit");

            waiterThread.Join();

            Assert.Less(log.IndexOf("Waiter+Enter"), log.IndexOf("Main+Exit"));
            Assert.Greater(log.IndexOf("Waiter-Enter"), log.IndexOf("Main-Exit"));
        }