summaryrefslogtreecommitdiff
path: root/java/src/RWMutex.java
diff options
context:
space:
mode:
authorirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-11-12 08:15:37 +0000
committerirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-11-12 08:15:37 +0000
commitb952cb6e5c920e390cddac1e3c8c6e07fe561738 (patch)
treef9dc5575ff0c85c0ee168212714a0f4b4cf8d65c /java/src/RWMutex.java
parent795c99a9a2eecff871b4cef86a40382d25a3afb5 (diff)
downloadATCD-b952cb6e5c920e390cddac1e3c8c6e07fe561738.tar.gz
new implementation of traditional conditions in java
Diffstat (limited to 'java/src/RWMutex.java')
-rw-r--r--java/src/RWMutex.java150
1 files changed, 110 insertions, 40 deletions
diff --git a/java/src/RWMutex.java b/java/src/RWMutex.java
index 8421e61a73e..eda77ff933c 100644
--- a/java/src/RWMutex.java
+++ b/java/src/RWMutex.java
@@ -6,17 +6,21 @@
* = FILENAME
* RWMutex.java
*
- *@author Ross Dargahi (rossd@krinfo.com) and Prashant Jain
+ *@author Irfan Pyarali
*
*************************************************/
+
package ACE.Concurrency;
+import ACE.OS.*;
+
/*******************************************************************************
* <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.
+* This implementation is based on the C++ version of ACE.
* </PRE><P><HR>
* <B> Notes </B>
* <UL>
@@ -30,7 +34,7 @@ public class RWMutex
* @exception InterruptedException Lock acquisition interrupted
**/
public void acquire()
- throws InterruptedException
+ throws InterruptedException
{
acquireWrite();
}
@@ -39,66 +43,132 @@ public class RWMutex
* Acquires the read lock
* @exception InterruptedException Lock acquisition interrupted
**/
- public synchronized void acquireRead()
- throws InterruptedException
+ public void acquireRead()
+ throws InterruptedException
{
- // Wait till there is an active writer, wait.
- while (this.mWriterActive_)
- wait();
+ // make sure we start with no exception
+ InterruptedException exception_ = null;
+
+ // grab lock
+ lock_.acquire ();
+
+ // Give preference to writers who are waiting.
+ while (referenceCount_ < 0 || numberOfWaitingWriters_ > 0)
+ {
+ numberOfWaitingReaders_++;
+ try
+ {
+ waitingReaders_.Wait ();
+ }
+ catch (InterruptedException exception)
+ {
+ // cache exception
+ exception_ = exception;
+ }
+ numberOfWaitingReaders_--;
+ }
+
+ if (exception_ == null)
+ // No errors
+ referenceCount_++;
- this.mNumReaders_++;
- }
+ // make sure this is released in all cases
+ lock_.release ();
+ if (exception_ != null)
+ // error: propogate
+ throw exception_;
+ }
+
/**
* Acquires the write lock
* @exception InterruptedException Lock acquisition interrupted
**/
- public synchronized void acquireWrite()
- throws InterruptedException
+ public void acquireWrite()
+ throws InterruptedException
{
- // If there is an active writer before us, then wait for it to finish
- // before proceeding
- while (this.mWriterActive_)
- wait();
+ // make sure we start with no exception
+ InterruptedException exception_ = null;
- // 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;
+ // grab lock
+ lock_.acquire ();
- while (this.mNumReaders_ > 0)
- wait();
-
- this.mWriterHoldsLock_ = true;
+ // Give preference to writers who are waiting.
+ while (referenceCount_ != 0)
+ {
+ numberOfWaitingWriters_++;
+ try
+ {
+ waitingWriters_.Wait ();
+ }
+ catch (InterruptedException exception)
+ {
+ // cache exception
+ exception_ = exception;
+ }
+ numberOfWaitingWriters_--;
+ }
+
+ if (exception_ == null)
+ // No errors
+ referenceCount_ = -1;
+
+ // make sure this is released in all cases
+ lock_.release ();
+
+ if (exception_ != null)
+ // error: propogate
+ throw exception_;
}
/**
* Release held lock
* @exception InterruptedException Lock acquisition interrupted
**/
- public synchronized void release()
+ public void release()
+ throws InterruptedException
{
- if (this.mWriterHoldsLock_)
+ lock_.acquire ();
+
+ // Releasing a reader.
+ if (referenceCount_ > 0)
+ referenceCount_--;
+ else
+ // Releasing a writer.
+ if (referenceCount_ == -1)
+ referenceCount_ = 0;
+
+ // Give preference to writers over readers...
+ if (numberOfWaitingWriters_ > 0)
{
- this.mWriterActive_ = false;
- this.mWriterHoldsLock_ = false;
+ waitingWriters_.signal ();
}
- else
+ else if (numberOfWaitingReaders_ > 0)
{
- this.mNumReaders_--;
+ waitingReaders_.broadcast ();
}
-
- notifyAll();
-
- }
-
- private int mNumReaders_;
- // Current number of readers
+
- private boolean mWriterActive_;
- // If true, a writer is active
+ lock_.release ();
+ }
- private boolean mWriterHoldsLock_;
- // If true, a writer holds the lock
+ private Mutex lock_ = new Mutex ();
+ // Serialize access to internal state.
+
+ private Condition waitingReaders_ = new Condition (lock_);
+ // Reader threads waiting to acquire the lock.
+
+ private int numberOfWaitingReaders_;
+ // Number of waiting readers.
+
+ private Condition waitingWriters_ = new Condition (lock_);
+ // Writer threads waiting to acquire the lock.
+
+ private int numberOfWaitingWriters_ = 0;
+ // Number of waiting writers.
+
+ private int referenceCount_ = 0;
+ // Value is -1 if writer has the lock, else this keeps track of the
+ // number of readers holding the lock.
}