Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jacomma/util/RdWrLock.java


1   /*
2    * $Source: /home/data/cvsroot/src/jacomma/util/RdWrLock.java,v $
3    * $Revision: 1.4 $
4    * $Date: 2000/10/28 20:09:08 $
5    *
6    * This file is part of the jacomma framework
7    * Copyright (c) 2000   Dimitrios Vyzovitis
8    *      mailto:dviz@egnatia.ee.auth.gr
9    *      
10   *
11   *      
12   *      
13   *      
14   *
15   *  This library is free software; you can redistribute it and/or modify
16   *  it under the terms of the GNU Library General Public License as published by
17   *  the Free Software Foundation; either version 2 of the License, or
18   *  (at your option) any later version.
19   *
20   *  This library is distributed in the hope that it will be useful,
21   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23   *  GNU Library General Public License for more details.
24   *
25   *  You should have received a copy of the GNU Library General Public License
26   *  along with this library; if not, write to the Free Software
27   *  Foundation, Inc., 59 Temple Place, Suite 330, 
28   *  Boston, MA  02111-1307  USA
29   */
30  
31  package jacomma.util;
32  
33  /**
34   * A recursive (re-enterant) read-write Lock implementation with single reader
35   * priviledge elevation and deadlock detection
36   **/
37  public class RdWrLock {
38    
39    private java.util.Map readers_;
40    private LockCount writer_;
41  
42    public RdWrLock( ) {
43      readers_ = new java.util.HashMap(  );
44    }
45  
46      public synchronized void rdlock() {
47      try {
48        while( !_try_rdlock() ) {
49          // Attempt to fix the 100% CPU utilization behavior incurred by LinuxThreads
50          Thread.currentThread().yield();
51          wait();
52        }
53      } catch ( InterruptedException exc ) {
54        throw new CheckedException( exc );
55      }
56    }
57      
58      /**
59     * Acquires a write-lock.
60       */
61      public synchronized void wrlock() {
62      try {
63        while( !_try_wrlock() )
64          if ( readers_.containsKey( Thread.currentThread() ) )
65            // priviledge elevation attempt failed
66            throw new IllegalStateException( "Potential Deadlock: Failed to elevate priviledges of Reader thread: " + Thread.currentThread() );
67        else {
68          // Attempt to fix the 100% CPU utilization behavior incurred by LinuxThreads
69          Thread.currentThread().yield();
70          wait();
71        }
72      } catch ( InterruptedException exc ) {
73        throw new CheckedException( exc );
74      }
75      }
76      
77  
78      /**
79     * @return true if a read-lock is successfully acquired.
80       */
81      public synchronized boolean try_rdlock() {
82      return _try_rdlock();
83      }
84      
85      /**
86     * @return true if a write-lock is succesfully acquired
87       */
88      public synchronized boolean try_wrlock() {
89      return _try_wrlock();
90      }
91  
92      /**
93     * Releases (decrements count) a lock ownder by the current thread
94     * Nothing happens if the thread is not a lock owner
95       */
96      public synchronized void unlock() {
97      if ( writer_ == null ) {
98        LockCount rd = (LockCount)readers_.get( Thread.currentThread() );
99        if ( rd != null
100          && rd.down() == 0 ) {
101         readers_.remove( rd.thread_ );
102         notify(); // only writers are waiting - notify one of them
103       }
104     } else if ( writer_.thread_ == Thread.currentThread() 
105           && writer_.down() == 0 ) {
106       writer_ = null;
107       notifyAll(); // potentially many readers and/or writers are waiting.
108     }
109     }
110 
111   private boolean _try_rdlock() {
112 
113     if ( writer_ == null ) {
114       LockCount count = (LockCount)readers_.get( Thread.currentThread() );
115       if ( count == null ) {
116         count = new LockCount( );
117         readers_.put( count.thread_, count );
118       }
119       count.up();
120       return true;
121     } else if ( writer_.thread_ == Thread.currentThread() ) {
122       writer_.up();
123       return true;
124     } else  
125       return false;
126 
127   }
128 
129   private boolean _try_wrlock() {
130     if ( writer_ == null ) {
131       writer_ = (LockCount)readers_.remove( Thread.currentThread() );
132       if ( readers_.size() > 0 ) {
133 
134         if ( writer_ != null ) {
135           // put back
136           readers_.put( writer_.thread_, writer_ );
137           writer_ = null;
138           return false;
139         }
140 
141       } else   if ( writer_ == null )
142         writer_ = new LockCount( );
143 
144     } else if ( writer_.thread_ != Thread.currentThread() ) {
145       return false;
146     }
147 
148     writer_.up();
149     return true;
150   }
151   
152   private class LockCount {
153     Thread thread_ = Thread.currentThread();
154     int count_ = 0;;
155         
156     int up() { return ++count_; }
157     int down() { return --count_; }
158     
159   }
160   
161 }