summaryrefslogtreecommitdiff
path: root/java/src/RWMutex.java
blob: 8421e61a73e660b86954df3f8154da9a11037c88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*************************************************
 *
 * = PACKAGE
 *    ACE.Concurrency
 *
 * = FILENAME
 *    RWMutex.java
 *
 *@author Ross Dargahi (rossd@krinfo.com) and Prashant Jain
 *
 *************************************************/
package ACE.Concurrency;

/*******************************************************************************
* <HR>
* <B> Description </B>
* <BR>
* This class increments a read/write lock. A read/write lock allows multiple
* readers or a single writer to access the guarded element.
* </PRE><P><HR>
* <B> Notes </B>
* <UL>
* <LI> This class does not support recursive semantics
* </UL>
*******************************************************************************/
public class RWMutex
{
  /**
   * Acquires the write lock
   * @exception InterruptedException Lock acquisition interrupted
   **/
  public void acquire()
       throws InterruptedException
  {
    acquireWrite();
  }

  /**
   * Acquires the read lock
   * @exception InterruptedException Lock acquisition interrupted
   **/
  public synchronized void acquireRead()
       throws InterruptedException
  {
    // Wait till there is an active writer, wait.
    while (this.mWriterActive_)
      wait();

    this.mNumReaders_++;
  }

  /**
   * Acquires the write lock
   * @exception InterruptedException Lock acquisition interrupted
   **/
  public synchronized void acquireWrite()
       throws InterruptedException
  {
    // If there is an active writer before us, then wait for it to finish
    // before proceeding
    while (this.mWriterActive_)
      wait();
    
    // Set the writer active flag to true, then wait for all readers to finish
    // with the lock. Note that no new readers will be able to grab the lock
    // since they will be blocking on the writer active flag in acquireRead()
    this.mWriterActive_ = true;
    
    while (this.mNumReaders_ > 0)
      wait();
   
    this.mWriterHoldsLock_ = true;
  }

  /**
   * Release held lock
   * @exception InterruptedException Lock acquisition interrupted
   **/
  public synchronized void release()
  {
    if (this.mWriterHoldsLock_)
      {
	this.mWriterActive_ = false;
	this.mWriterHoldsLock_ = false;
      }
    else
      {
	this.mNumReaders_--;
      }

    notifyAll();

  }

  private int mNumReaders_;
  // Current number of readers
    
  private boolean mWriterActive_;
  // If true, a writer is active

  private boolean mWriterHoldsLock_;
  // If true, a writer holds the lock
}