// other thread is loading or creating object and haven't finished
try {
_waitCount++;
wait();
} catch (InterruptedException e) {
throw new LockNotGrantedException("Thread interrupted acquiring lock!", e);
} 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;
}
_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");
}
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 (internalTimeout == 0) {
if (LOG.isDebugEnabled()) {
LOG.debug("Timeout on " + this.toString() + " by " + tx);
}
throw new LockNotGrantedException(
(write ? "persist.writeLockTimeout" : "persist.readLockTimeout")
+ _oid + "/" + _id + " by " + tx);
}
if (LOG.isDebugEnabled()) {
LOG.debug("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, except);
}
if (_deleted) {