System.Threading.Tests.ReaderWriterLockTests.BasicLockTest C# (CSharp) Метод

BasicLockTest() приватный Метод

private BasicLockTest ( ) : void
Результат void
        public static void BasicLockTest()
        {
            var trwl = new TestReaderWriterLock();
            TestLockCookie tlc;
            var threadReady = new AutoResetEvent(false);
            var continueThread = new AutoResetEvent(false);
            Action checkForThreadErrors, waitForThread;
            Thread t =
                ThreadTestHelpers.CreateGuardedThread(out checkForThreadErrors, out waitForThread, () =>
                {
                    TestLockCookie tlc2;
                    Action switchToMainThread =
                        () =>
                        {
                            threadReady.Set();
                            continueThread.CheckedWait();
                        };

                    switchToMainThread();

                    // Multiple readers from multiple threads
                    {
                        trwl.AcquireReaderLock();
                        trwl.AcquireReaderLock();
                        switchToMainThread();
                        trwl.ReleaseReaderLock();
                        switchToMainThread();
                        trwl.ReleaseReaderLock();
                        switchToMainThread();

                        trwl.AcquireReaderLock();
                        trwl.ReleaseReaderLock();
                        switchToMainThread();
                    }

                    // What can be done when a read lock is held
                    {
                        trwl.AcquireReaderLock();
                        switchToMainThread();

                        // Any thread can take a read lock
                        trwl.AcquireReaderLock();
                        trwl.ReleaseReaderLock();
                        switchToMainThread();

                        // No thread can take a write lock
                        trwl.AcquireWriterLock(TimeoutExceptionHResult);
                        trwl.AcquireReaderLock();
                        trwl.UpgradeToWriterLock(TimeoutExceptionHResult);
                        trwl.ReleaseReaderLock();
                        switchToMainThread();

                        trwl.ReleaseReaderLock();
                        switchToMainThread();

                        // Owning thread releases read lock when upgrading
                        trwl.AcquireWriterLock();
                        trwl.ReleaseWriterLock();
                        switchToMainThread();

                        // Owning thread cannot upgrade if there are other readers or writers
                        trwl.AcquireReaderLock();
                        switchToMainThread();
                        trwl.ReleaseReaderLock();
                        trwl.AcquireWriterLock();
                        switchToMainThread();
                        trwl.ReleaseWriterLock();
                        switchToMainThread();
                    }

                    // What can be done when a write lock is held
                    {
                        // Write lock acquired through AcquireWriteLock is exclusive
                        trwl.AcquireWriterLock();
                        switchToMainThread();
                        trwl.ReleaseWriterLock();
                        switchToMainThread();

                        // Write lock acquired through upgrading is also exclusive
                        trwl.AcquireReaderLock();
                        tlc2 = trwl.UpgradeToWriterLock();
                        switchToMainThread();
                        trwl.DowngradeFromWriterLock(tlc2);
                        trwl.ReleaseReaderLock();
                        switchToMainThread();

                        // Write lock acquired through restore is also exclusive
                        trwl.AcquireWriterLock();
                        tlc = trwl.ReleaseLock();
                        trwl.RestoreLock(tlc);
                        switchToMainThread();
                        trwl.ReleaseWriterLock();
                        switchToMainThread();
                    }
                });
            t.IsBackground = true;
            t.Start();

            Action beginSwitchToBackgroundThread = () => continueThread.Set();
            Action endSwitchToBackgroundThread =
                () =>
                {
                    try
                    {
                        threadReady.CheckedWait();
                    }
                    finally
                    {
                        checkForThreadErrors();
                    }
                };
            Action switchToBackgroundThread =
                () =>
                {
                    beginSwitchToBackgroundThread();
                    endSwitchToBackgroundThread();
                };
            endSwitchToBackgroundThread();

            // Multiple readers from muliple threads
            {
                trwl.AcquireReaderLock();
                trwl.AcquireReaderLock();
                switchToBackgroundThread(); // AcquireReaderLock * 2
                trwl.ReleaseReaderLock();
                switchToBackgroundThread(); // ReleaseReaderLock

                // Release/restore the read lock while a read lock is held by another thread
                tlc = trwl.ReleaseLock();
                trwl.RestoreLock(tlc);

                switchToBackgroundThread(); // ReleaseReaderLock

                // Downgrade to read lock allows another thread to acquire read lock
                tlc = trwl.UpgradeToWriterLock();
                trwl.DowngradeFromWriterLock(tlc);
                switchToBackgroundThread(); // AcquireReaderLock, ReleaseReaderLock

                trwl.ReleaseReaderLock();
            }

            // What can be done when a read lock is held
            {
                switchToBackgroundThread(); // AcquireReaderLock
                {
                    // Any thread can take a read lock
                    trwl.AcquireReaderLock();
                    trwl.ReleaseReaderLock();
                    switchToBackgroundThread(); // same as above

                    // No thread can take a write lock
                    trwl.AcquireWriterLock(TimeoutExceptionHResult);
                    trwl.AcquireReaderLock();
                    trwl.UpgradeToWriterLock(TimeoutExceptionHResult);
                    switchToBackgroundThread(); // same as above
                    trwl.ReleaseReaderLock();

                    // Other threads cannot upgrade to a write lock, but the owning thread can
                    trwl.AcquireReaderLock();
                    trwl.UpgradeToWriterLock(TimeoutExceptionHResult);
                    trwl.ReleaseReaderLock();
                }
                switchToBackgroundThread(); // ReleaseReaderLock

                // Owning thread releases read lock when upgrading
                trwl.AcquireReaderLock();
                beginSwitchToBackgroundThread(); // AcquireWriterLock: background thread gets blocked
                trwl.UpgradeToWriterLock(); // unblocks background thread: ReleaseWriterLock
                trwl.ReleaseWriterLock();
                endSwitchToBackgroundThread();

                // Owning thread cannot upgrade if there are other readers or writers
                trwl.AcquireReaderLock();
                switchToBackgroundThread(); // AcquireReaderLock
                trwl.UpgradeToWriterLock(TimeoutExceptionHResult);
                trwl.ReleaseReaderLock();
                switchToBackgroundThread(); // ReleaseReaderLock, AcquireWriterLock
                trwl.UpgradeToWriterLock(TimeoutExceptionHResult);
                switchToBackgroundThread(); // ReleaseWriterLock
            }

            // What can be done when a write lock is held
            {
                trwl.AcquireWriterLock();
                TestLockCookie restoreToWriteLockTlc = trwl.ReleaseLock();
                Action verifyCannotAcquireLock =
                    () =>
                    {
                        trwl.AcquireReaderLock(TimeoutExceptionHResult);
                        trwl.AcquireWriterLock(TimeoutExceptionHResult);
                        trwl.UpgradeToWriterLock(TimeoutExceptionHResult);
                    };
                Action verifyCanAcquireLock =
                    () =>
                    {
                        trwl.AcquireReaderLock();
                        tlc = trwl.UpgradeToWriterLock();
                        trwl.DowngradeFromWriterLock(tlc);
                        trwl.ReleaseReaderLock();
                        trwl.AcquireWriterLock();
                        trwl.ReleaseWriterLock();
                        trwl.RestoreLock(restoreToWriteLockTlc.Clone());
                        trwl.ReleaseWriterLock();
                    };

                // Write lock acquired through AcquireWriteLock is exclusive
                switchToBackgroundThread(); // AcquireWriterLock
                verifyCannotAcquireLock();
                switchToBackgroundThread(); // ReleaseWriterLock
                verifyCanAcquireLock();

                // Write lock acquired through upgrading is also exclusive
                switchToBackgroundThread(); // AcquireReaderLock, UpgradeToWriterLock
                verifyCannotAcquireLock();
                switchToBackgroundThread(); // DowngradeFromWriterLock, ReleaseReaderLock
                verifyCanAcquireLock();

                // Write lock acquired through restore is also exclusive
                switchToBackgroundThread(); // AcquireWriterLock, ReleaseLock, RestoreLock
                verifyCannotAcquireLock();
                switchToBackgroundThread(); // ReleaseWriterLock
                verifyCanAcquireLock();
            }

            beginSwitchToBackgroundThread();
            waitForThread();
            trwl.Dispose();
        }