package com.sleepycat.je.latch; import java.util.concurrent.locks.ReentrantReadWriteLock; import com.sleepycat.je.DatabaseException; import com.sleepycat.je.dbi.EnvironmentImpl; import de.ovgu.cide.jakutil.*; /** * Java5SharedLatchImpl provides an implementation of the SharedLatch * interface. By using a wrapper class we can avoid link errors when we run in * Java 1.4 JVMs. LatchSupport will only reference this class if it knows that * the ReentrantReadWriteLock class is available at runtime through * Class.forName(). LatchSupport only references this class through the * SharedLatch interface and only constructs this using * Class.forName("Java5LatchImpl").newInstance(); */ class Java5SharedLatchImpl extends ReentrantReadWriteLock implements SharedLatch { private String name; private boolean noteLatch; Java5SharedLatchImpl(){ super(EnvironmentImpl.getFairLatches()); } /** * Set the latch name, used for latches in objects instantiated from the * log. */ public void setName( String name){ this.name=name; } /** * If noteLatch is true, then track latch usage in the latchTable. */ public void setNoteLatch( boolean noteLatch){ this.noteLatch=noteLatch; } /** * Acquire a latch for exclusive/write access. * Wait for the latch if some other thread is holding it. If there are * threads waiting for access, they will be granted the latch on a FIFO * basis if fair latches are set. When the method returns, the latch is * held for exclusive access. * @throws LatchException if the latch is already held by the current * thread for exclusive access. */ public void acquireExclusive() throws DatabaseException { try { if (isWriteLockedByCurrentThread()) { throw new LatchException(name + " already held"); } writeLock().lock(); assert (noteLatch ? noteLatch() : true); } finally { assert EnvironmentImpl.maybeForceYield(); } } public boolean acquireExclusiveNoWait() throws DatabaseException { try { if (isWriteLockedByCurrentThread()) { throw new LatchException(name + " already held"); } boolean ret=writeLock().tryLock(); assert (noteLatch ? noteLatch() : true); return ret; } finally { assert EnvironmentImpl.maybeForceYield(); } } /** * Acquire a latch for shared/read access. */ public void acquireShared() throws DatabaseException { try { readLock().lock(); assert (noteLatch ? noteLatch() : true); } finally { assert EnvironmentImpl.maybeForceYield(); } } /** * Release an exclusive or shared latch. If there are other thread(s) * waiting for the latch, they are woken up and granted the latch. */ public void release() throws LatchNotHeldException { try { if (isWriteLockedByCurrentThread()) { writeLock().unlock(); return; } readLock().unlock(); } catch ( IllegalMonitorStateException IMSE) { return; } finally { assert (noteLatch ? unNoteLatch() : true); } } /** * Only call under the assert system. This records latching by thread. */ private boolean noteLatch() throws LatchException { return LatchSupport.latchTable.noteLatch(this); } /** * Only call under the assert system. This records latching by thread. */ private boolean unNoteLatch(){ return LatchSupport.latchTable.unNoteLatch(this,name); } }