[concurrency-interest] RE: ReentrantWriterPreferenceReadWriteLock -- Deadlock if reader releases lock more times than it aquires lock

Mazda.Hewitt@ubsw.com Mazda.Hewitt@ubsw.com
Wed, 4 Dec 2002 13:33:12 -0000


Hi, 

I completly understand your point and I agree with you.  But I think that it would be better if the code gracefully dealt with the situation where the lock is released by someone who doesn't own it.  Perhaps it would be better to throw an exception when this situation occurs.  At the moment it throws an NullPointerException (which appears odd to a user unless they know the code) and then the lock is deadlocked.  It would be better if it threw an exception which was informative as to the cause and then left the lock in a workable state.  Unless there is a known perfomace problem with checking to see if the owner of the lock is the one releasing it, I don't see a problem with doing this.

Mazda

-----Original Message-----
From: "David Holmes" <dholmes@dltech.com.au>
To: <concurrency-interest@altair.cs.oswego.edu>
Subject: RE: [concurrency-interest] ReentrantWriterPreferenceReadWriteLock -- Deadlock if reader releases lock more times than it aquires lock
Date: Tue, 3 Dec 2002 07:01:00 +1000

Mazda Hewitt wrote:
> ReentrantWriterPreferenceReadWriteLock appears to deadlock
> if a reader releases the lock more times than it aquires
> it.  In this case the reader is releasing a lock that it
> doesn't own.  I understand that the number of aquires
> should exactly match the number of releases and you have to
> be careful to realease all locks that are aquired.  But as
> you can see in this example it is easy to accidently
> release the lock too many times.  It is also easy to assume
> that this won't matter.

Thanks for the posting.

While I'm all for making misuse of these things more difficult, and
making the consequence of misuse less drastic (assuming the price of
that is not too high), I must emphasise the importance of the correct
usage of the try/finally construct - it is something that a number of
books and articles often get wrong.

[The following is not a lecture to the original poster but rather a
clarification for anyone reading the list archive at a later date.]

In the example, we have:

    public void run(){
      try {
        if ( lock.readLock().attempt(100)){
          System.out.println("Reader " + getName()+" Reading");
          sleep (2000);
        }
        else{
           System.out.println("Reader " + getName()+" Failed to get
lock");
        }
      }
      catch (InterruptedException ex) {
        interrupt();
      }
      finally{
        lock.readLock().release();
      }
    }

which is an incorrect usage of the try/finally construct as the
finally clause is executed even if the Lock.attempt failed. With
paired actions like acquire/attempt and release, it is crucial to
remember that the first action occurs *outside* of the try block:

  public void run(){
    if ( lock.readLock().attempt(100)){
      try {
        System.out.println("Reader " + getName()+" Reading");
        sleep (2000);
      }
      catch (InterruptedException ex) {
        interrupt();
      }
      finally{
        lock.readLock().release();
      }
   }
   else{
     System.out.println("Reader " + getName()+" Failed to get lock");
   }
 }

Now sometimes the structure of code is such that doing try/finally
correctly, and dealing with exceptions, can lead to awkward structure.
In such cases you will often find the code in the finally clause
protected by a condition - such as checking a reference to an I/O
stream for null before closing it.

<end lecture> :)

David Holmes



--__--__--

_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@altair.cs.oswego.edu
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest


End of Concurrency-interest Digest

Visit our website at http://www.ubswarburg.com

This message contains confidential information and is intended only 
for the individual named.  If you are not the named addressee you 
should not disseminate, distribute or copy this e-mail.  Please 
notify the sender immediately by e-mail if you have received this 
e-mail by mistake and delete this e-mail from your system.

E-mail transmission cannot be guaranteed to be secure or error-free 
as information could be intercepted, corrupted, lost, destroyed, 
arrive late or incomplete, or contain viruses.  The sender therefore 
does not accept liability for any errors or omissions in the contents 
of this message which arise as a result of e-mail transmission.  If 
verification is required please request a hard-copy version.  This 
message is provided for informational purposes and should not be 
construed as a solicitation or offer to buy or sell any securities or 
related financial instruments.