// other thread is loading or creating object and haven't finished
try {
_waitCount++;
wait();
} catch ( InterruptedException e ) {
throw new LockNotGrantedException("Thread interrupted acquiring lock!");
} finally {
_waitCount--;
}
} else if ( _writeLock == tx ) {
//throw new IllegalStateException("Transaction: "+tx+" has already hold the write lock on "+_oid+
// " Acquire shouldn't be called twice");
return;
} else if ( _readLock == null && _writeLock == null && write ) {
// no transaction hold any lock,
_confirmWaiting = tx;
_confirmWaitingAction = ACTION_WRITE;
return;
} else if ( _readLock == null && _writeLock == null && !write ) {
// no transaction hold any lock,
if ( _object == null ) {
_confirmWaiting = tx;
_confirmWaitingAction = ACTION_READ;
return;
} else {
_readLock = new LinkedTx( tx, null );
return;
}
} else if ( _readLock != null && !write ) {
// already a transaction holding read lock, can acquire read lock
LinkedTx linked = _readLock;
while ( linked != null ) {
if ( linked.tx == tx )
throw new IllegalStateException("Transaction: "+tx+" has already hold the write lock on "+_oid+
" Acquire shouldn't be called twice");
//return;
linked = linked.next;
}
// if not already in readLock
_readLock = new LinkedTx( tx, _readLock );
return;
} else {
// other transaction holding writeLock, waits for write
// or, other transaction holding readLock, waiting for read
if ( timeout == 0 ) {
if ( TRACE )
System.out.println( "Timeout on " + this.toString() + " by " + tx );
throw new LockNotGrantedException( (write ? "persist.writeLockTimeout" :
"persist.readLockTimeout") + _oid + "/" + _id + " by " + tx );
}
if ( TRACE )
System.out.println( "Waiting on " + this.toString() + " by " + tx );
// Detect possibility of dead-lock. Must remain in wait-on-lock
// position until lock is granted or exception thrown.
tx.setWaitOnLock( this );
detectDeadlock( tx, 10 );
// Must wait for lock and then attempt to reacquire
if ( write )
_writeWaiting = new LinkedTx( tx, _writeWaiting );
else
_readWaiting = new LinkedTx( tx, _readWaiting );
// Wait until notified or timeout elapses. Must detect
// when notified but object deleted (i.e. locks released)
// All waiting transactions are notified at once, but once
// notified a race condition starts to acquire new lock
try {
long waittime = endtime - System.currentTimeMillis();
wait( waittime<0? 0: waittime );
} catch ( InterruptedException except ) {
// If the thread is interrupted, come out with the proper message
throw new LockNotGrantedException( write ? "persist.writeLockTimeout" :
"persist.readLockTimeout" + _oid + "/" + _id + " by " + tx );
}
if ( _deleted )
// If object has been deleted while waiting for lock, report deletion.