001: // Spatial Index Library
002: //
003: // Copyright (C) 2002 Navel Ltd.
004: //
005: // This library is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU Lesser General Public
007: // License as published by the Free Software Foundation; either
008: // version 2.1 of the License, or (at your option) any later version.
009: //
010: // This library is distributed in the hope that it will be useful,
011: // but WITHOUT ANY WARRANTY; without even the implied warranty of
012: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: // Lesser General Public License for more details.
014: //
015: // You should have received a copy of the GNU Lesser General Public
016: // License aint with this library; if not, write to the Free Software
017: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: //
019: // Contact information:
020: // Mailing address:
021: // Marios Hadjieleftheriou
022: // University of California, Riverside
023: // Department of Computer Science
024: // Surge Building, Room 310
025: // Riverside, CA 92521
026: //
027: // Email:
028: // marioh@cs.ucr.edu
029:
030: // Readers/Writers lock by Allen Holub
031: package org.geotools.caching.spatialindex.spatialindex;
032:
033: import java.util.*;
034:
035: public class RWLock {
036: private int active_readers;
037: private int waiting_readers;
038: private int active_writers;
039: private final LinkedList writer_locks = new LinkedList();
040:
041: public synchronized void read_lock() {
042: if ((active_writers == 0) && (writer_locks.size() == 0)) {
043: ++active_readers;
044: } else {
045: ++waiting_readers;
046:
047: try {
048: wait();
049: } catch (InterruptedException e) {
050: }
051: }
052: }
053:
054: public synchronized boolean read_lock_noblock() {
055: if ((active_writers == 0) && (writer_locks.size() == 0)) {
056: ++active_readers;
057:
058: return true;
059: }
060:
061: return false;
062: }
063:
064: public synchronized void read_unlock() {
065: if (--active_readers == 0) {
066: notify_writers();
067: }
068: }
069:
070: public void write_lock() {
071: Object lock = new Object();
072:
073: synchronized (lock) {
074: synchronized (this ) {
075: boolean okay_to_write = (writer_locks.size() == 0)
076: && (active_readers == 0)
077: && (active_writers == 0);
078:
079: if (okay_to_write) {
080: ++active_writers;
081:
082: return; // the "return" jumps over the "wait" call
083: }
084:
085: writer_locks.addLast(lock);
086: }
087:
088: try {
089: lock.wait();
090: } catch (InterruptedException e) {
091: }
092: }
093: }
094:
095: synchronized public boolean write_lock_noblock() {
096: if ((writer_locks.size() == 0) && (active_readers == 0)
097: && (active_writers == 0)) {
098: ++active_writers;
099:
100: return true;
101: }
102:
103: return false;
104: }
105:
106: public synchronized void write_unlock() {
107: --active_writers;
108:
109: if (waiting_readers > 0) { // priority to waiting readers
110: notify_readers();
111: } else {
112: notify_writers();
113: }
114: }
115:
116: private void notify_readers() // must be accessed from a
117: { // synchronized method
118: active_readers += waiting_readers;
119: waiting_readers = 0;
120: notifyAll();
121: }
122:
123: private void notify_writers() // must be accessed from a
124: { // synchronized method
125:
126: if (writer_locks.size() > 0) {
127: Object oldest = writer_locks.removeFirst();
128: ++active_writers;
129:
130: synchronized (oldest) {
131: oldest.notify();
132: }
133: }
134: }
135: }
|