123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #region Apache License
- //
- // Licensed to the Apache Software Foundation (ASF) under one or more
- // contributor license agreements. See the NOTICE file distributed with
- // this work for additional information regarding copyright ownership.
- // The ASF licenses this file to you under the Apache License, Version 2.0
- // (the "License"); you may not use this file except in compliance with
- // the License. You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- #endregion
- #if (!NETCF)
- #define HAS_READERWRITERLOCK
- #endif
- #if NET_4_0 || MONO_4_0
- #define HAS_READERWRITERLOCKSLIM
- #endif
- using System;
- namespace log4net.Util
- {
- /// <summary>
- /// Defines a lock that supports single writers and multiple readers
- /// </summary>
- /// <remarks>
- /// <para>
- /// <c>ReaderWriterLock</c> is used to synchronize access to a resource.
- /// At any given time, it allows either concurrent read access for
- /// multiple threads, or write access for a single thread. In a
- /// situation where a resource is changed infrequently, a
- /// <c>ReaderWriterLock</c> provides better throughput than a simple
- /// one-at-a-time lock, such as <see cref="System.Threading.Monitor"/>.
- /// </para>
- /// <para>
- /// If a platform does not support a <c>System.Threading.ReaderWriterLock</c>
- /// implementation then all readers and writers are serialized. Therefore
- /// the caller must not rely on multiple simultaneous readers.
- /// </para>
- /// </remarks>
- /// <author>Nicko Cadell</author>
- public sealed class ReaderWriterLock
- {
- #region Instance Constructors
- /// <summary>
- /// Constructor
- /// </summary>
- /// <remarks>
- /// <para>
- /// Initializes a new instance of the <see cref="ReaderWriterLock" /> class.
- /// </para>
- /// </remarks>
- public ReaderWriterLock()
- {
- #if HAS_READERWRITERLOCK
- #if HAS_READERWRITERLOCKSLIM
- m_lock = new System.Threading.ReaderWriterLockSlim(System.Threading.LockRecursionPolicy.SupportsRecursion);
- #else
- m_lock = new System.Threading.ReaderWriterLock();
- #endif
- #endif
- }
- #endregion Private Instance Constructors
-
- #region Public Methods
- /// <summary>
- /// Acquires a reader lock
- /// </summary>
- /// <remarks>
- /// <para>
- /// <see cref="AcquireReaderLock"/> blocks if a different thread has the writer
- /// lock, or if at least one thread is waiting for the writer lock.
- /// </para>
- /// </remarks>
- public void AcquireReaderLock()
- {
- #if HAS_READERWRITERLOCK
- #if HAS_READERWRITERLOCKSLIM
- // prevent ThreadAbort while updating state, see https://issues.apache.org/jira/browse/LOG4NET-443
- try { }
- finally
- {
- m_lock.EnterReadLock();
- }
- #else
- m_lock.AcquireReaderLock(-1);
- #endif
- #else
- System.Threading.Monitor.Enter(this);
- #endif
- }
- /// <summary>
- /// Decrements the lock count
- /// </summary>
- /// <remarks>
- /// <para>
- /// <see cref="ReleaseReaderLock"/> decrements the lock count. When the count
- /// reaches zero, the lock is released.
- /// </para>
- /// </remarks>
- public void ReleaseReaderLock()
- {
- #if HAS_READERWRITERLOCK
- #if HAS_READERWRITERLOCKSLIM
- m_lock.ExitReadLock();
- #else
- m_lock.ReleaseReaderLock();
- #endif
- #else
- System.Threading.Monitor.Exit(this);
- #endif
- }
- /// <summary>
- /// Acquires the writer lock
- /// </summary>
- /// <remarks>
- /// <para>
- /// This method blocks if another thread has a reader lock or writer lock.
- /// </para>
- /// </remarks>
- public void AcquireWriterLock()
- {
- #if HAS_READERWRITERLOCK
- #if HAS_READERWRITERLOCKSLIM
- // prevent ThreadAbort while updating state, see https://issues.apache.org/jira/browse/LOG4NET-443
- try { }
- finally
- {
- m_lock.EnterWriteLock();
- }
- #else
- m_lock.AcquireWriterLock(-1);
- #endif
- #else
- System.Threading.Monitor.Enter(this);
- #endif
- }
- /// <summary>
- /// Decrements the lock count on the writer lock
- /// </summary>
- /// <remarks>
- /// <para>
- /// ReleaseWriterLock decrements the writer lock count.
- /// When the count reaches zero, the writer lock is released.
- /// </para>
- /// </remarks>
- public void ReleaseWriterLock()
- {
- #if HAS_READERWRITERLOCK
- #if HAS_READERWRITERLOCKSLIM
- m_lock.ExitWriteLock();
- #else
- m_lock.ReleaseWriterLock();
- #endif
- #else
- System.Threading.Monitor.Exit(this);
- #endif
- }
- #endregion Public Methods
- #region Private Members
- #if HAS_READERWRITERLOCK
- #if HAS_READERWRITERLOCKSLIM
- private System.Threading.ReaderWriterLockSlim m_lock;
- #else
- private System.Threading.ReaderWriterLock m_lock;
- #endif
- #endif
- #endregion
- }
- }
|