Beispiel #1
0
        /// <summary>
        /// Acquires the write lock if it is not held by another thread
        /// within the given waiting time and <see cref="System.Threading.Thread.Interrupt()"/> has not been called on the current thread
        /// </summary>
        /// <remarks>
        /// Acquires the write lock if neither the read nor write lock
        /// are held by another thread
        /// and returns immediately with the value <see lang="true"/>,
        /// setting the write lock hold count to one. If this lock has been
        /// set to use a fair ordering policy then an available lock
        /// <b>will not</b> be acquired if any other threads are
        /// waiting for the write lock. This is in contrast to the <see cref="Spring.Threading.Locks.WriterLock.TryLock()"/>
        /// If you want a timed <see cref="Spring.Threading.Locks.WriterLock.TryLock()"/>
        /// that does permit barging on a fair lock, then combine the
        /// timed and un-timed forms together:
        ///
        /// <code>
        /// if (lock.TryLock() || lock.tryLock(timeSpan) ) { ... }
        /// </code>
        ///
        /// <p/>
        /// If the current thread already holds this lock then the
        /// hold count is incremented by one and the method returns
        /// <see lang="true"/>.
        ///
        /// <p/>
        /// If the lock is held by another thread then the current
        /// thread becomes disabled for thread scheduling purposes and
        /// lies dormant until one of three things happens:
        ///
        /// <ul>
        /// <li>The write lock is acquired by the current thread</li>
        /// <li>Some other thread calls <see cref="System.Threading.Thread.Interrupt()"/>
        /// on the current thread</li>
        /// <li>The specified <see cref="System.TimeSpan"/> elapses</li>
        /// </ul>
        ///
        /// <p/>
        /// If the write lock is acquired then the value <see lang="true"/> is
        /// returned and the write lock hold count is set to one.
        ///
        /// <p/>
        /// If the current thread has <see cref="System.Threading.Thread.Interrupt()"/> called on it while acquiring
        /// the write lock, then a <see cref="System.Threading.ThreadInterruptedException"/> is thrown.
        ///
        /// <p/>
        /// If the specified <see cref="System.TimeSpan"/> elapses then the value
        /// <see lang="false"/> is returned.  If the time is less than or
        /// equal to zero, the method will not wait at all.
        ///
        /// <p/>
        /// In this implementation, as this method is an explicit
        /// interruption point, preference is given to responding to
        /// the interrupt over normal or reentrant acquisition of the
        /// lock, and over reporting the elapse of the waiting time.
        ///
        /// </remarks>
        /// <param name="durationToWait">the time to wait for the write lock</param>
        /// <returns> <see lang="true"/> if the lock was free and was acquired
        /// by the current thread, or the write lock was already held by the
        /// current thread; and <see lang="false"/> if the waiting time
        /// elapsed before the lock could be acquired.
        /// </returns>
        ///
        /// <exception cref="System.Threading.ThreadInterruptedException">if the current thread is interrupted.</exception>
        public override bool TryLock(TimeSpan durationToWait)
        {
            ThreadInterruptedException ie = null;

            lock (this)
            {
                if (durationToWait.TotalMilliseconds <= 0)
                {
                    return(ReentrantReadWriteLock.StartWrite());
                }
                else if (ReentrantReadWriteLock.StartWriteFromNewWriter())
                {
                    return(true);
                }
                else
                {
                    DateTime deadline = DateTime.Now.Add(durationToWait);
                    for (;;)
                    {
                        try
                        {
                            Monitor.Wait(this, durationToWait);
                        }
                        catch (ThreadInterruptedException ex)
                        {
                            ReentrantReadWriteLock.CancelWaitingWriter();
                            Monitor.Pulse(this);
                            ie = ex;
                            break;
                        }
                        if (ReentrantReadWriteLock.StartWriteFromWaitingWriter())
                        {
                            return(true);
                        }
                        else
                        {
                            if (deadline.Subtract(DateTime.Now).TotalMilliseconds <= 0)
                            {
                                ReentrantReadWriteLock.CancelWaitingWriter();
                                Monitor.Pulse(this);
                                break;
                            }
                        }
                    }
                }
            }

            ReentrantReadWriteLock.SignallerReaderLock.SignalWaiters();
            if (ie != null)
            {
                throw ie;
            }
            else
            {
                return(false);
            }
        }
Beispiel #2
0
        /// <summary>
        ///	Acquires the write lock unless <see cref="System.Threading.Thread.Interrupt()"/> is called on the current thread
        /// </summary>
        /// <remarks>
        /// Acquires the write lock if neither the read nor write locks
        /// are held by another thread
        /// and returns immediately, setting the write lock hold count to
        /// one.
        ///
        /// <p/>
        /// If the current thread already holds this lock then the
        /// hold count is incremented by one and the method returns
        /// immediately.
        ///
        /// <p/>
        /// If the lock is held by another thread then the current
        /// thread becomes disabled for thread scheduling purposes and
        /// lies dormant until one of two things happens:
        ///
        /// <ul>
        /// <li>The write lock is acquired by the current thread.</li>
        /// <li>Some other thread calls <see cref="System.Threading.Thread.Interrupt()"/> on the current thread.</li>
        /// </ul>
        ///
        /// <p/>
        /// If the write lock is acquired by the current thread then the
        /// lock hold count is set to one.
        ///
        /// <p/>
        /// If the current thread:
        /// <ul>
        /// <li>has its interrupted status set on entry to this method</li>
        /// <li><see cref="System.Threading.Thread.Interrupt()"/> is called on the thread while acquiring the write lock.</li>
        /// </ul>
        ///
        /// then a <see cref="System.Threading.ThreadInterruptedException"/> is thrown and the current
        /// thread's interrupted status is cleared.
        ///
        /// <p/>
        /// In this implementation, as this method is an explicit
        /// interruption point, preference is given to responding to
        /// the interrupt over normal or reentrant acquisition of the
        /// lock.
        ///
        /// </remarks>
        /// <exception cref="System.Threading.ThreadInterruptedException">if the current thread is interrupted.</exception>
        public override IDisposable LockInterruptibly()
        {
            ThreadInterruptedException ie = null;

            lock (this)
            {
                if (!ReentrantReadWriteLock.StartWriteFromNewWriter())
                {
                    for (;;)
                    {
                        try
                        {
                            Monitor.Wait(this);
                            if (ReentrantReadWriteLock.StartWriteFromWaitingWriter())
                            {
                                return(this);
                            }
                        }
                        catch (ThreadInterruptedException ex)
                        {
                            ReentrantReadWriteLock.CancelWaitingWriter();
                            Monitor.Pulse(this);
                            ie = ex;
                            break;
                        }
                    }
                }
            }
            if (ie != null)
            {
                // Fall through outside synch on interrupt.
                //  On exception, we may need to signal readers.
                //  It is not worth checking here whether it is strictly necessary.
                ReentrantReadWriteLock.SignallerReaderLock.SignalWaiters();
                throw ie;
            }
            return(this);
        }