Exemplo n.º 1
0
            public void Dispose()
            {
                // release lock
                switch (_status)
                {
                    case ReadWriteLockStatus.Write:
                        {
                            var oldCounter =
                                Concurrency.Atomic(
                                    ref _lockable._counter,
                                    counter => counter.SetWriterCount(counter.WriterCount() - 1).SetReaderCount(counter.ReaderCount()));
                            Debug.Assert(oldCounter.WriterCount() > 0);

                            if (oldCounter.WriterCount() > 0)
                            {
                #if READWRITELOCK_TRACE
                                Debug.Print("{0} #{1} release WriteLock", GetHashCode(), Thread.CurrentThread.ManagedThreadId);
                #endif
                                _lockable._writeThreadID = 0;
                            }
                            else
                                throw new InvalidOperationException("No write lock is held");
                            _status = ReadWriteLockStatus.None;
                        }
                        break;

                    case ReadWriteLockStatus.Read:
                        {
                            var oldCounter =
                                Concurrency.Atomic(
                                    ref _lockable._counter,
                                    counter => counter.SetReaderCount(counter.ReaderCount() - 1).SetWriterCount(counter.WriterCount()));
                            if (oldCounter.ReaderCount() > 0)
                            {
                #if READWRITELOCK_TRACE
                                Debug.Print("{0} #{1} release ReadLock", GetHashCode(), Thread.CurrentThread.ManagedThreadId);
                #endif
                            }
                            else
                                throw new InvalidOperationException("No read lock is held");
                        }
                        break;

                    default:
                        throw new InvalidOperationException("No lock is held");
                }

                GC.SuppressFinalize(this);
            }
Exemplo n.º 2
0
            public void Downgrade()
            {
                // update status
                switch (_status)
                {
                    case ReadWriteLockStatus.Read:
                        // already downgraded
                        return;
                    case ReadWriteLockStatus.None:
                        throw new InvalidOperationException("Cannot downgrade lock that has been released");
                }

                // switch write lock to read lock
                _lockable._writeThreadID = 0;
                Concurrency.Atomic(ref _lockable._counter, counter => 0.SetReaderCount(counter.ReaderCount() + 1).SetWriterCount(counter.WriterCount() - 1));
                _status = ReadWriteLockStatus.Read;
            }
Exemplo n.º 3
0
 internal Lock(ReadWriteLockable lockable, ReadWriteLockStatus status)
 {
     _lockable = lockable;
     _status = status;
 }