System.Threading.ReaderWriterLock.ReleaseWriterLock C# (CSharp) Method

ReleaseWriterLock() public method

public ReleaseWriterLock ( ) : void
return void
        public void ReleaseWriterLock()
        {
            if (_writerID != GetCurrentThreadID())
            {
                throw GetNotOwnerException();
            }

            Debug.Assert((_state & LockStates.ReadersMask) == 0);
            Debug.Assert((_state & LockStates.Writer) != 0);
            Debug.Assert(_writerLevel > 0);

            // Check for nested release
            --_writerLevel;
            if (_writerLevel > 0)
            {
                return;
            }

            // Not a writer any more
            _writerID = InvalidThreadID;
            bool cacheEvents;
            ManualResetEventSlim readerEvent = null;
            AutoResetEvent writerEvent = null;
            int currentState = _state;
            int knownState;
            do
            {
                cacheEvents = false;
                knownState = currentState;
                int modifyState = -LockStates.Writer;

                if ((knownState & LockStates.WaitingReadersMask) != 0)
                {
                    readerEvent = TryGetOrCreateReaderEvent();
                    if (readerEvent == null)
                    {
                        // Wait for some time and try again. Since a WaitingReaders bit is set, the event would usually
                        // already be created (if the waiting reader that called AcquireReaderLock is already waiting on the
                        // event, it would have created the event). However, AcquireReaderLock adds WaitingReader to the
                        // state before trying to create the event.
                        //
                        // This is such a situation, where the event has not yet been created, and likely due to the system
                        // being low on resources, this thread failed to create the event. We don't want to throw here,
                        // because it could potentially leave waiters waiting and cause a deadlock.
                        //
                        // Instead, we let the threads that set the WaitingReader bit throw, and here, just wait and try
                        // again. In a low-resource situation, eventually, all such new waiting readers would throw, and the
                        // WaitingReaders bits would not be set anymore, breaking the loop and releasing this thread.
                        Helpers.Sleep(100);
                        currentState = _state;
                        knownState = 0;
                        Debug.Assert(currentState != knownState);
                        continue;
                    }
                    modifyState += LockStates.ReaderSignaled;
                }
                else if ((knownState & LockStates.WaitingWritersMask) != 0)
                {
                    writerEvent = TryGetOrCreateWriterEvent();
                    if (writerEvent == null)
                    {
                        // Similar to above, wait for some time and try again
                        Helpers.Sleep(100);
                        currentState = _state;
                        knownState = 0;
                        Debug.Assert(currentState != knownState);
                        continue;
                    }
                    modifyState += LockStates.WriterSignaled;
                }
                else if (knownState == LockStates.Writer && (_readerEvent != null || _writerEvent != null))
                {
                    cacheEvents = true;
                    modifyState += LockStates.CachingEvents;
                }

                Debug.Assert((knownState & LockStates.ReadersMask) == 0);
                Debug.Assert((knownState & LockStates.Writer) != 0);
                currentState = Interlocked.CompareExchange(ref _state, knownState + modifyState, knownState);
            } while (currentState != knownState);

            // Check for waiting readers
            if ((knownState & LockStates.WaitingReadersMask) != 0)
            {
                Debug.Assert((_state & LockStates.ReaderSignaled) != 0);
                Debug.Assert(readerEvent != null);
                readerEvent.Set();
            }
            // Check for waiting writers
            else if ((knownState & LockStates.WaitingWritersMask) != 0)
            {
                Debug.Assert((_state & LockStates.WriterSignaled) != 0);
                Debug.Assert(writerEvent != null);
                writerEvent.Set();
            }
            // Check for the need to release events
            else if (cacheEvents)
            {
                ReleaseEvents();
            }
        }

Usage Example

Ejemplo n.º 1
0
        public static bool ReLoadMap()
        {
            try
            {
                Dictionary <int, MapPoint> tempMaps     = new Dictionary <int, MapPoint>();
                Dictionary <int, Map>      tempMapInfos = new Dictionary <int, Map>();

                if (LoadMap(tempMaps, tempMapInfos))
                {
                    m_lock.AcquireWriterLock(Timeout.Infinite);
                    try
                    {
                        _maps     = tempMaps;
                        _mapInfos = tempMapInfos;
                        return(true);
                    }
                    catch
                    { }
                    finally
                    {
                        m_lock.ReleaseWriterLock();
                    }
                }
            }
            catch (Exception e)
            {
                if (log.IsErrorEnabled)
                {
                    log.Error("ReLoadMap", e);
                }
            }

            return(false);
        }
All Usage Examples Of System.Threading.ReaderWriterLock::ReleaseWriterLock