// Spatial Index Library
//
// Copyright (C) 2002 Navel Ltd.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation;
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License aint with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Contact information:
// Mailing address:
// Marios Hadjieleftheriou
// University of California, Riverside
// Department of Computer Science
// Surge Building, Room 310
// Riverside, CA 92521
//
// Email:
// marioh@cs.ucr.edu
// Readers/Writers lock by Allen Holub
package org.geotools.caching.spatialindex;
import java.util.LinkedList;
public class RWLock {
private int active_readers;
private int waiting_readers;
private int active_writers;
private final LinkedList writer_locks = new LinkedList();
public synchronized void read_lock() {
if ((active_writers == 0) && (writer_locks.size() == 0)) {
++active_readers;
} else {
++waiting_readers;
try {
wait();
} catch (InterruptedException e) {
}
}
}
public synchronized boolean read_lock_noblock() {
if ((active_writers == 0) && (writer_locks.size() == 0)) {
++active_readers;
return true;
}
return false;
}
public synchronized void read_unlock() {
if (--active_readers == 0) {
notify_writers();
}
}
public void write_lock() {
Object lock = new Object();
synchronized (lock) {
synchronized (this) {
boolean okay_to_write = (writer_locks.size() == 0) && (active_readers == 0)
&& (active_writers == 0);
if (okay_to_write) {
++active_writers;
return; // the "return" jumps over the "wait" call
}
writer_locks.addLast(lock);
}
try {
lock.wait();
} catch (InterruptedException e) {
}
}
}
synchronized public boolean write_lock_noblock() {
if ((writer_locks.size() == 0) && (active_readers == 0) && (active_writers == 0)) {
++active_writers;
return true;
}
return false;
}
public synchronized void write_unlock() {
--active_writers;
if (waiting_readers > 0) { // priority to waiting readers
notify_readers();
} else {
notify_writers();
}
}
private void notify_readers() // must be accessed from a
{ // synchronized method
active_readers += waiting_readers;
waiting_readers = 0;
notifyAll();
}
private void notify_writers() // must be accessed from a
{ // synchronized method
if (writer_locks.size() > 0) {
Object oldest = writer_locks.removeFirst();
++active_writers;
synchronized (oldest) {
oldest.notify();
}
}
}
}