[Jsxe-cvs] SF.net SVN: jsxe: [1083] branches/jsxe2/src/net/sourceforge/jsxe/util/ReadWriteLock.java
Status: Inactive
Brought to you by:
ian_lewis
|
From: <ian...@us...> - 2006-07-28 22:47:07
|
Revision: 1083 Author: ian_lewis Date: 2006-07-28 15:46:52 -0700 (Fri, 28 Jul 2006) ViewCVS: http://svn.sourceforge.net/jsxe/?rev=1083&view=rev Log Message: ----------- Added the ReadWriteLock class Added Paths: ----------- branches/jsxe2/src/net/sourceforge/jsxe/util/ReadWriteLock.java Added: branches/jsxe2/src/net/sourceforge/jsxe/util/ReadWriteLock.java =================================================================== --- branches/jsxe2/src/net/sourceforge/jsxe/util/ReadWriteLock.java (rev 0) +++ branches/jsxe2/src/net/sourceforge/jsxe/util/ReadWriteLock.java 2006-07-28 22:46:52 UTC (rev 1083) @@ -0,0 +1,207 @@ +/* +ReadWriteLock.java +:tabSize=4:indentSize=4:noTabs=true: +:folding=explicit:collapseFolds=1: + +Copyright (C) 2001 Peter Graves + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +Optionally, you may find a copy of the GNU General Public License +from http://www.fsf.org/copyleft/gpl.txt +*/ + +package net.sourceforge.jsxe.util; + +import java.util.Vector; + +/** + * Implements consumer/producer locking scemantics. + * @author Peter Graves + * @version $Id: ReadWriteLock.java,v 1.7 2004/02/14 19:02:49 spestov Exp $ + * The lock tries to be re-entrant when called from the same thread in some + * cases. + * + * The following is ok: + * read lock + * read lock + * read unlock + * read unlock + * + * write lock + * read lock + * read unlock + * write unlock + * + * The following is not ok: + * + * read lock + * write lock + * write unlock + * read unlock + * + * write lock + * write lock + * write unlock + * write unlock + */ +public class ReadWriteLock +{ + //{{{ readLock() method + public synchronized void readLock() + { + // this seems to make nested readLock() calls work okay. + // but I have no idea if it actually fixes things or not. + if (activeReaders != 0 || allowRead()) + { + ++activeReaders; + //readers.addElement(Thread.currentThread()); + return; + } + ++waitingReaders; + while (!allowRead()) + { + try + { + wait(); + } + catch (InterruptedException e) + { + --waitingReaders; // Roll back state. + Log.log(Log.ERROR,this,e); + return; + } + } + --waitingReaders; + ++activeReaders; + readers.addElement(Thread.currentThread()); + } //}}} + + //{{{ readUnlock() method + public synchronized void readUnlock() + { + if(activeReaders == 0) + throw new InternalError("Unbalanced readLock()/readUnlock() calls"); + + --activeReaders; + //readers.removeElement(Thread.currentThread()); + notifyAll(); + } //}}} + + //{{{ writeLock() method + public synchronized void writeLock() + { + if (writerThread != null) + { + // Write in progress. + if (Thread.currentThread() == writerThread) + { + // Same thread. + ++lockCount; + return; + } + } + if (allowWrite()) + { + claimWriteLock(); + return; + } + + ++waitingWriters; + while (!allowWrite()) + { + try + { + wait(); + } + catch (InterruptedException e) + { + --waitingWriters; + Log.log(Log.ERROR,this,e); + return; + } + } + --waitingWriters; + claimWriteLock(); + } //}}} + + //{{{ writeUnlock() method + public synchronized void writeUnlock() + { + if(activeWriters != 1 || lockCount <= 0) + throw new InternalError("Unbalanced writeLock()/writeUnlock() calls"); + + if(Thread.currentThread() != writerThread) + throw new InternalError("writeUnlock() from wrong thread"); + + if (--lockCount == 0) + { + --activeWriters; + writerThread = null; + notifyAll(); + } + } //}}} + + //{{{ isWriteLocked() method + public synchronized boolean isWriteLocked() + { + //Debug.assert(activeWriters == 0 || activeWriters == 1); + return activeWriters == 1; + } //}}} + + //{{{ Private members + + //{{{ Instance variables + private int activeReaders; + private int activeWriters; + private int waitingReaders; + private int waitingWriters; + private Vector readers = new Vector(); + + private Thread writerThread; + private int lockCount; + //}}} + + //{{{ allowRead() method + private final boolean allowRead() + { + return (Thread.currentThread() == writerThread) + || (waitingWriters == 0 && activeWriters == 0); + } //}}} + + //{{{ allowWrite() method + private final boolean allowWrite() + { + /*Thread current = Thread.currentThread(); + for(int i = 0; i < readers.size(); i++) + { + if(readers.elementAt(i) == current) + throw new InternalError("Cannot nest writeLock() inside readLock()"); + }*/ + + return activeReaders == 0 && activeWriters == 0; + } //}}} + + //{{{ claimWriteLock() method + private void claimWriteLock() + { + ++activeWriters; + //Debug.assert(writerThread == null); + writerThread = Thread.currentThread(); + //Debug.assert(lockCount == 0); + lockCount = 1; + } //}}} + + //}}} +} Property changes on: branches/jsxe2/src/net/sourceforge/jsxe/util/ReadWriteLock.java ___________________________________________________________________ Name: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |