use of org.exist.util.LockException in project exist by eXist-db.
the class GetIndex method eval.
@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
if (args[1].isEmpty())
return Sequence.EMPTY_SEQUENCE;
final String id = args[0].getStringValue();
final NodeProxy node = (NodeProxy) args[1].itemAt(0);
final SortIndexWorker index = (SortIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(SortIndex.ID);
long pos = 0;
try {
pos = index.getIndex(id, node);
} catch (final EXistException e) {
throw new XPathException(this, e.getMessage(), e);
} catch (final LockException e) {
throw new XPathException(this, "Caught lock error while searching index. Giving up.", e);
}
return pos < 0 ? Sequence.EMPTY_SEQUENCE : new IntegerValue(pos, Type.LONG);
}
use of org.exist.util.LockException in project exist by eXist-db.
the class LockManager method acquireBtreeReadLock.
/**
* Acquire a WRITE_LOCK on a {@link org.exist.storage.btree.BTree}
*
* @param btreeFileName the filename of the BTree
*
* @return the lock for the BTree
*
* @throws LockException if the lock could not be acquired
*/
public ManagedLock<ReentrantLock> acquireBtreeReadLock(final String btreeFileName) throws LockException {
final long groupId = System.nanoTime();
final ReentrantLock lock = getBTreeLock(btreeFileName);
try {
lockTable.attempt(groupId, btreeFileName, LockType.BTREE, Lock.LockMode.READ_LOCK);
lock.lockInterruptibly();
lockTable.acquired(groupId, btreeFileName, LockType.BTREE, Lock.LockMode.READ_LOCK);
} catch (final InterruptedException e) {
lockTable.attemptFailed(groupId, btreeFileName, LockType.BTREE, Lock.LockMode.READ_LOCK);
throw new LockException("Unable to acquire READ_LOCK for: " + btreeFileName, e);
}
return new ManagedLock(lock, () -> {
lock.unlock();
lockTable.released(groupId, btreeFileName, LockType.BTREE, Lock.LockMode.READ_LOCK);
});
}
use of org.exist.util.LockException in project exist by eXist-db.
the class LockManager method acquireBtreeWriteLock.
/**
* Acquire a WRITE_LOCK on a {@link org.exist.storage.btree.BTree}
*
* @param btreeFileName the filename of the BTree
*
* @return the lock for the BTree
*
* @throws LockException if the lock could not be acquired
*/
public ManagedLock<ReentrantLock> acquireBtreeWriteLock(final String btreeFileName) throws LockException {
final long groupId = System.nanoTime();
final ReentrantLock lock = getBTreeLock(btreeFileName);
try {
lockTable.attempt(groupId, btreeFileName, LockType.BTREE, Lock.LockMode.WRITE_LOCK);
lock.lockInterruptibly();
lockTable.acquired(groupId, btreeFileName, LockType.BTREE, Lock.LockMode.WRITE_LOCK);
} catch (final InterruptedException e) {
lockTable.attemptFailed(groupId, btreeFileName, LockType.BTREE, Lock.LockMode.WRITE_LOCK);
throw new LockException("Unable to acquire WRITE_LOCK for: " + btreeFileName, e);
}
return new ManagedLock(lock, () -> {
lock.unlock();
lockTable.released(groupId, btreeFileName, LockType.BTREE, Lock.LockMode.WRITE_LOCK);
});
}
use of org.exist.util.LockException in project exist by eXist-db.
the class LockManager method acquirePathWriteLock.
/**
* Acquires a WRITE_LOCK on a path (and implicitly all descendant paths).
*
* @param path The path for which a lock is requested.
* @param lockParent true if we should also explicitly write lock the parent path.
*
* @return A WRITE_LOCK on the path.
*/
LockGroup acquirePathWriteLock(final LockType lockType, final XmldbURI path, final boolean lockParent) throws LockException {
final XmldbURI[] segments = path.getPathSegments();
final long groupId = System.nanoTime();
String pathStr = "";
final Tuple3<MultiLock, Lock.LockMode, String>[] locked = new Tuple3[segments.length];
for (int i = 0; i < segments.length; i++) {
pathStr += '/' + segments[i].toString();
final Lock.LockMode lockMode;
if (lockParent && i + 2 == segments.length) {
// parent
lockMode = Lock.LockMode.WRITE_LOCK;
} else if (i + 1 == segments.length) {
// leaf
lockMode = Lock.LockMode.WRITE_LOCK;
} else {
if (!pathsMultiWriter) {
// single-writer/multi-reader
lockMode = Lock.LockMode.WRITE_LOCK;
} else {
// multi-writer/multi-reader
lockMode = Lock.LockMode.INTENTION_WRITE;
}
}
final MultiLock lock = getPathLock(pathStr);
if (upgradeCheck && lockMode == Lock.LockMode.WRITE_LOCK && (lock.getIntentionReadHoldCount() > 0 || lock.getReadHoldCount() > 0)) {
throw new LockException("Lock upgrading would lead to a self-deadlock: " + pathStr);
}
if (warnWaitOnReadForWrite && lockMode == Lock.LockMode.WRITE_LOCK) {
if (lock.getIntentionReadLockCount() > 0) {
LOG.warn("About to acquire WRITE_LOCK for: {}, but INTENTION_READ_LOCK held by other thread(s): ", pathStr);
} else if (lock.getReadLockCount() > 0) {
LOG.warn("About to acquire WRITE_LOCK for: {}, but READ_LOCK held by other thread(s): ", pathStr);
}
}
lockTable.attempt(groupId, pathStr, lockType, lockMode);
if (lock(lock, lockMode)) {
locked[i] = new Tuple3<>(lock, lockMode, pathStr);
lockTable.acquired(groupId, pathStr, lockType, lockMode);
} else {
lockTable.attemptFailed(groupId, pathStr, lockType, lockMode);
unlockAll(locked, l -> lockTable.released(groupId, l._3, lockType, l._2));
throw new LockException("Unable to acquire " + lockType + " " + lockMode + " for: " + pathStr);
}
}
return new LockGroup(groupId, locked);
}
use of org.exist.util.LockException in project exist by eXist-db.
the class LockManager method acquirePathReadLock.
/**
* Acquires a READ_LOCK on a database path (and implicitly all descendant paths).
*
* @param lockType The type of the lock
* @param path The path for which a lock is requested.
*
* @return A READ_LOCK on the Collection.
*
* @throws LockException if a lock error occurs
*/
public LockGroup acquirePathReadLock(final LockType lockType, final XmldbURI path) throws LockException {
final XmldbURI[] segments = path.getPathSegments();
final long groupId = System.nanoTime();
String pathStr = "";
final Tuple3<MultiLock, Lock.LockMode, String>[] locked = new Tuple3[segments.length];
for (int i = 0; i < segments.length; i++) {
pathStr += '/' + segments[i].toString();
final Lock.LockMode lockMode;
if (i + 1 == segments.length) {
// leaf
lockMode = Lock.LockMode.READ_LOCK;
} else {
// ancestor
lockMode = Lock.LockMode.INTENTION_READ;
}
final MultiLock lock = getPathLock(pathStr);
lockTable.attempt(groupId, pathStr, lockType, lockMode);
if (lock(lock, lockMode)) {
locked[i] = new Tuple3<>(lock, lockMode, pathStr);
lockTable.acquired(groupId, pathStr, lockType, lockMode);
} else {
lockTable.attemptFailed(groupId, pathStr, lockType, lockMode);
unlockAll(locked, l -> lockTable.released(groupId, l._3, lockType, l._2));
throw new LockException("Unable to acquire " + lockType + " " + lockMode + " for: " + pathStr);
}
}
return new LockGroup(groupId, locked);
}
Aggregations