PageRenderTime 87ms CodeModel.GetById 81ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre3/org/gjt/sp/util/ReadWriteLock.java

#
Java | 175 lines | 108 code | 19 blank | 48 comment | 28 complexity | 91bac359e79462b39c435e29dedd48c1 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
 27public class ReadWriteLock
 28{
 29	//{{{ readLock() method
 30	public synchronized void readLock()
 31	{
 32		// this seems to make nested readLock() calls work okay.
 33		// but I have no idea if it actually fixes things or not.
 34		if (activeReaders != 0 || allowRead())
 35		{
 36			++activeReaders;
 37			//readers.addElement(Thread.currentThread());
 38			return;
 39		}
 40		++waitingReaders;
 41		while (!allowRead())
 42		{
 43			try
 44			{
 45				wait();
 46			}
 47			catch (InterruptedException e)
 48			{
 49				--waitingReaders; // Roll back state.
 50				Log.log(Log.ERROR,this,e);
 51				return;
 52			}
 53		}
 54		--waitingReaders;
 55		++activeReaders;
 56		readers.addElement(Thread.currentThread());
 57	} //}}}
 58
 59	//{{{ readUnlock() method
 60	public synchronized void readUnlock()
 61	{
 62		if(activeReaders == 0)
 63			throw new InternalError("Unbalanced readLock()/readUnlock() calls");
 64
 65		--activeReaders;
 66		//readers.removeElement(Thread.currentThread());
 67		notifyAll();
 68	} //}}}
 69
 70	//{{{ writeLock() method
 71	public synchronized void writeLock()
 72	{
 73		if (writerThread != null)
 74		{
 75			// Write in progress.
 76			if (Thread.currentThread() == writerThread)
 77			{
 78				// Same thread.
 79				++lockCount;
 80				return;
 81			}
 82		}
 83		if (allowWrite())
 84		{
 85			claimWriteLock();
 86			return;
 87		}
 88
 89		++waitingWriters;
 90		while (!allowWrite())
 91		{
 92			try
 93			{
 94				wait();
 95			}
 96			catch (InterruptedException e)
 97			{
 98				--waitingWriters;
 99				Log.log(Log.ERROR,this,e);
100				return;
101			}
102		}
103		--waitingWriters;
104		claimWriteLock();
105	} //}}}
106
107	//{{{ writeUnlock() method
108	public synchronized void writeUnlock()
109	{
110		if(activeWriters != 1 || lockCount <= 0)
111			throw new InternalError("Unbalanced writeLock()/writeUnlock() calls");
112
113		if(Thread.currentThread() != writerThread)
114			throw new InternalError("writeUnlock() from wrong thread");
115
116		if (--lockCount == 0)
117		{
118			--activeWriters;
119			writerThread = null;
120			notifyAll();
121		}
122	} //}}}
123
124	//{{{ isWriteLocked() method
125	public synchronized boolean isWriteLocked()
126	{
127		//Debug.assert(activeWriters == 0 || activeWriters == 1);
128		return activeWriters == 1;
129	} //}}}
130
131	//{{{ Private members
132
133	//{{{ Instance variables
134	private int activeReaders;
135	private int activeWriters;
136	private int waitingReaders;
137	private int waitingWriters;
138	private Vector readers = new Vector();
139
140	private Thread writerThread;
141	private int lockCount;
142	//}}}
143
144	//{{{ allowRead() method
145	private final boolean allowRead()
146	{
147		return (Thread.currentThread() == writerThread)
148			|| (waitingWriters == 0 && activeWriters == 0);
149	} //}}}
150
151	//{{{ allowWrite() method
152	private final boolean allowWrite()
153	{
154		/*Thread current = Thread.currentThread();
155		for(int i = 0; i < readers.size(); i++)
156		{
157			if(readers.elementAt(i) == current)
158				throw new InternalError("Cannot nest writeLock() inside readLock()");
159		}*/
160
161		return activeReaders == 0 && activeWriters == 0;
162	} //}}}
163
164	//{{{ claimWriteLock() method
165	private void claimWriteLock()
166	{
167		++activeWriters;
168		//Debug.assert(writerThread == null);
169		writerThread = Thread.currentThread();
170		//Debug.assert(lockCount == 0);
171		lockCount = 1;
172	} //}}}
173
174	//}}}
175}