PageRenderTime 101ms CodeModel.GetById 89ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/util/ReadWriteLock.java

#
Java | 180 lines | 108 code | 19 blank | 53 comment | 28 complexity | adeed918a85070ef7aa8968806cce598 MD5 | raw file
  1/*
  2 * ReadWriteLock.java
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2001 Peter Graves
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or (at your option) any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package org.gjt.sp.util;
 24
 25import java.util.Vector;
 26
 27/**
 28 * Implements consumer/producer locking scemantics.
 29 * @author Peter Graves
 30 * @version $Id: ReadWriteLock.java 4455 2003-01-31 04:49:31Z spestov $
 31 */
 32public class ReadWriteLock
 33{
 34	//{{{ readLock() method
 35	public synchronized void readLock()
 36	{
 37		// this seems to make nested readLock() calls work okay.
 38		// but I have no idea if it actually fixes things or not.
 39		if (activeReaders != 0 || allowRead())
 40		{
 41			++activeReaders;
 42			//readers.addElement(Thread.currentThread());
 43			return;
 44		}
 45		++waitingReaders;
 46		while (!allowRead())
 47		{
 48			try
 49			{
 50				wait();
 51			}
 52			catch (InterruptedException e)
 53			{
 54				--waitingReaders; // Roll back state.
 55				Log.log(Log.ERROR,this,e);
 56				return;
 57			}
 58		}
 59		--waitingReaders;
 60		++activeReaders;
 61		readers.addElement(Thread.currentThread());
 62	} //}}}
 63
 64	//{{{ readUnlock() method
 65	public synchronized void readUnlock()
 66	{
 67		if(activeReaders == 0)
 68			throw new InternalError("Unbalanced readLock()/readUnlock() calls");
 69
 70		--activeReaders;
 71		//readers.removeElement(Thread.currentThread());
 72		notifyAll();
 73	} //}}}
 74
 75	//{{{ writeLock() method
 76	public synchronized void writeLock()
 77	{
 78		if (writerThread != null)
 79		{
 80			// Write in progress.
 81			if (Thread.currentThread() == writerThread)
 82			{
 83				// Same thread.
 84				++lockCount;
 85				return;
 86			}
 87		}
 88		if (allowWrite())
 89		{
 90			claimWriteLock();
 91			return;
 92		}
 93
 94		++waitingWriters;
 95		while (!allowWrite())
 96		{
 97			try
 98			{
 99				wait();
100			}
101			catch (InterruptedException e)
102			{
103				--waitingWriters;
104				Log.log(Log.ERROR,this,e);
105				return;
106			}
107		}
108		--waitingWriters;
109		claimWriteLock();
110	} //}}}
111
112	//{{{ writeUnlock() method
113	public synchronized void writeUnlock()
114	{
115		if(activeWriters != 1 || lockCount <= 0)
116			throw new InternalError("Unbalanced writeLock()/writeUnlock() calls");
117
118		if(Thread.currentThread() != writerThread)
119			throw new InternalError("writeUnlock() from wrong thread");
120
121		if (--lockCount == 0)
122		{
123			--activeWriters;
124			writerThread = null;
125			notifyAll();
126		}
127	} //}}}
128
129	//{{{ isWriteLocked() method
130	public synchronized boolean isWriteLocked()
131	{
132		//Debug.assert(activeWriters == 0 || activeWriters == 1);
133		return activeWriters == 1;
134	} //}}}
135
136	//{{{ Private members
137
138	//{{{ Instance variables
139	private int activeReaders;
140	private int activeWriters;
141	private int waitingReaders;
142	private int waitingWriters;
143	private Vector readers = new Vector();
144
145	private Thread writerThread;
146	private int lockCount;
147	//}}}
148
149	//{{{ allowRead() method
150	private final boolean allowRead()
151	{
152		return (Thread.currentThread() == writerThread)
153			|| (waitingWriters == 0 && activeWriters == 0);
154	} //}}}
155
156	//{{{ allowWrite() method
157	private final boolean allowWrite()
158	{
159		/*Thread current = Thread.currentThread();
160		for(int i = 0; i < readers.size(); i++)
161		{
162			if(readers.elementAt(i) == current)
163				throw new InternalError("Cannot nest writeLock() inside readLock()");
164		}*/
165
166		return activeReaders == 0 && activeWriters == 0;
167	} //}}}
168
169	//{{{ claimWriteLock() method
170	private void claimWriteLock()
171	{
172		++activeWriters;
173		//Debug.assert(writerThread == null);
174		writerThread = Thread.currentThread();
175		//Debug.assert(lockCount == 0);
176		lockCount = 1;
177	} //}}}
178
179	//}}}
180}