示例#1
0
        private LockDetails GetReadLockDetails(int threadId, bool create)
        {
            int         i;
            LockDetails lockDetails;

            for (i = 0; i < read_locks.Length; i++)
            {
                lockDetails = read_locks[i];
                if (lockDetails == null)
                {
                    break;
                }
                if (lockDetails.ThreadId == threadId)
                {
                    return(lockDetails);
                }
            }
            if (!create)
            {
                return(null);
            }
            if (i == read_locks.Length)
            {
                Array.Resize(ref read_locks, read_locks.Length * 2);
            }
            lockDetails          = (read_locks[i] = new LockDetails());
            lockDetails.ThreadId = threadId;
            return(lockDetails);
        }
        LockDetails GetReadLockDetails(int threadId, bool create)
        {
            int         i;
            LockDetails ld;

            for (i = 0; i < read_locks.Length; ++i)
            {
                ld = read_locks[i];
                if (ld == null)
                {
                    break;
                }

                if (ld.ThreadId == threadId)
                {
                    return(ld);
                }
            }

            if (!create)
            {
                return(null);
            }

            if (i == read_locks.Length)
            {
                Array.Resize(ref read_locks, read_locks.Length * 2);
            }

            ld          = read_locks[i] = new LockDetails();
            ld.ThreadId = threadId;
            return(ld);
        }
示例#3
0
        public bool TryEnterReadLock(int millisecondsTimeout)
        {
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("millisecondsTimeout");
            }
            if (read_locks == null)
            {
                throw new ObjectDisposedException(null);
            }
            if (Thread.CurrentThread == write_thread)
            {
                throw new LockRecursionException("Read lock cannot be acquired while write lock is held");
            }
            EnterMyLock();
            LockDetails readLockDetails = GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, create: true);

            if (readLockDetails.ReadLocks != 0)
            {
                ExitMyLock();
                throw new LockRecursionException("Recursive read lock can only be aquired in SupportsRecursion mode");
            }
            readLockDetails.ReadLocks++;
            while (true)
            {
                if (owners >= 0 && numWriteWaiters == 0)
                {
                    owners++;
                    ExitMyLock();
                    return(true);
                }
                if (millisecondsTimeout == 0)
                {
                    ExitMyLock();
                    return(false);
                }
                if (readEvent == null)
                {
                    LazyCreateEvent(ref readEvent, makeAutoResetEvent: false);
                }
                else if (!WaitOnEvent(readEvent, ref numReadWaiters, millisecondsTimeout))
                {
                    break;
                }
            }
            return(false);
        }
示例#4
0
        public bool TryEnterWriteLock(int millisecondsTimeout)
        {
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("millisecondsTimeout");
            }
            if (read_locks == null)
            {
                throw new ObjectDisposedException(null);
            }
            if (IsWriteLockHeld)
            {
                throw new LockRecursionException();
            }
            EnterMyLock();
            LockDetails readLockDetails = GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, create: false);

            if (readLockDetails != null && readLockDetails.ReadLocks > 0)
            {
                ExitMyLock();
                throw new LockRecursionException("Write lock cannot be acquired while read lock is held");
            }
            while (true)
            {
                if (owners == 0)
                {
                    owners       = -1;
                    write_thread = Thread.CurrentThread;
                    break;
                }
                if (owners == 1 && upgradable_thread == Thread.CurrentThread)
                {
                    owners       = -1;
                    write_thread = Thread.CurrentThread;
                    break;
                }
                if (millisecondsTimeout == 0)
                {
                    ExitMyLock();
                    return(false);
                }
                if (upgradable_thread == Thread.CurrentThread)
                {
                    if (upgradeEvent == null)
                    {
                        LazyCreateEvent(ref upgradeEvent, makeAutoResetEvent: false);
                        continue;
                    }
                    if (numUpgradeWaiters != 0)
                    {
                        ExitMyLock();
                        throw new ApplicationException("Upgrading lock to writer lock already in process, deadlock");
                    }
                    if (!WaitOnEvent(upgradeEvent, ref numUpgradeWaiters, millisecondsTimeout))
                    {
                        return(false);
                    }
                }
                else if (writeEvent == null)
                {
                    LazyCreateEvent(ref writeEvent, makeAutoResetEvent: true);
                }
                else if (!WaitOnEvent(writeEvent, ref numWriteWaiters, millisecondsTimeout))
                {
                    return(false);
                }
            }
            ExitMyLock();
            return(true);
        }
示例#5
0
        LockDetails GetReadLockDetails(int threadId, bool create)
        {
            int i;
            LockDetails ld;
            for (i = 0; i < read_locks.Length; ++i) {
                ld = read_locks [i];
                if (ld == null)
                    break;

                if (ld.ThreadId == threadId)
                    return ld;
            }

            if (!create)
                return null;

            if (i == read_locks.Length)
                Array.Resize (ref read_locks, read_locks.Length * 2);

            ld = read_locks [i] = new LockDetails ();
            ld.ThreadId = threadId;
            return ld;
        }
        public bool TryEnterWriteLock(int millisecondsTimeout)
        {
            if (millisecondsTimeout < Timeout.Infinite)
            {
                throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout));
            }

            if (read_locks == null)
            {
                throw new ObjectDisposedException(null);
            }

            if (IsWriteLockHeld)
            {
                throw new LockRecursionException();
            }

            EnterMyLock();

            LockDetails ld = GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, false);

            if (ld != null && ld.ReadLocks > 0)
            {
                ExitMyLock();
                throw new LockRecursionException("Write lock cannot be acquired while read lock is held");
            }

            while (true)
            {
                // There is no contention, we are done
                if (owners == 0)
                {
                    // Indicate that we have a writer
                    owners       = -1;
                    write_thread = Thread.CurrentThread;
                    break;
                }

                // If we are the thread that took the Upgradable read lock
                if (owners == 1 && upgradable_thread == Thread.CurrentThread)
                {
                    owners       = -1;
                    write_thread = Thread.CurrentThread;
                    break;
                }

                // If the request is to probe.
                if (millisecondsTimeout == 0)
                {
                    ExitMyLock();
                    return(false);
                }

                // We need to wait, figure out what kind of waiting.

                if (upgradable_thread == Thread.CurrentThread)
                {
                    // We are the upgradable thread, register our interest.

                    if (upgradeEvent == null)
                    {
                        LazyCreateEvent(ref upgradeEvent, false);

                        // since we left the lock, start over.
                        continue;
                    }

                    if (numUpgradeWaiters > 0)
                    {
                        ExitMyLock();
                        throw new ApplicationException("Upgrading lock to writer lock already in process, deadlock");
                    }

                    if (!WaitOnEvent(upgradeEvent, ref numUpgradeWaiters, millisecondsTimeout))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (writeEvent == null)
                    {
                        LazyCreateEvent(ref writeEvent, true);

                        // since we left the lock, retry
                        continue;
                    }
                    if (!WaitOnEvent(writeEvent, ref numWriteWaiters, millisecondsTimeout))
                    {
                        return(false);
                    }
                }
            }

            Debug.Assert(owners == -1, "Owners is not -1");
            ExitMyLock();
            return(true);
        }
        public bool TryEnterReadLock(int millisecondsTimeout)
        {
            if (millisecondsTimeout < Timeout.Infinite)
            {
                throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout));
            }

            if (read_locks == null)
            {
                throw new ObjectDisposedException(null);
            }

            if (Thread.CurrentThread == write_thread)
            {
                throw new LockRecursionException("Read lock cannot be acquired while write lock is held");
            }

            EnterMyLock();

            LockDetails ld = GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, true);

            if (ld.ReadLocks != 0)
            {
                ExitMyLock();
                throw new LockRecursionException("Recursive read lock can only be acquired in SupportsRecursion mode");
            }
            ++ld.ReadLocks;

            while (true)
            {
                // Easy case, no contention
                // owners >= 0 means there might be readers (but no writer)
                if (owners >= 0 && numWriteWaiters == 0)
                {
                    owners++;
                    break;
                }

                // If the request is to probe.
                if (millisecondsTimeout == 0)
                {
                    ExitMyLock();
                    return(false);
                }

                // We need to wait.  Mark that we have waiters and wait.
                if (readEvent == null)
                {
                    LazyCreateEvent(ref readEvent, false);
                    // since we left the lock, start over.
                    continue;
                }

                if (!WaitOnEvent(readEvent, ref numReadWaiters, millisecondsTimeout))
                {
                    return(false);
                }
            }
            ExitMyLock();

            return(true);
        }