package org.basex.core;
import java.util.LinkedList;
import org.basex.util.Util;
/**
* Management of executing read/write processes.
* Supports multiple readers, limited by {@link MainProp#PARALLEL},
* and a single writer (readers/writer lock).
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
final class Lock {
/** Queue for all waiting processes. */
private final LinkedList<Object> queue = new LinkedList<Object>();
/** Mutex object. */
private final Object mutex = new Object();
/** Database context. */
private final Context ctx;
/** Number of active readers. */
private int readers;
/** Writer flag. */
private boolean writer;
/**
* Default constructor.
* @param c context
*/
Lock(final Context c) {
ctx = c;
}
/**
* Modifications before executing a command.
* @param w writing flag
*/
void lock(final boolean w) {
final Object o = new Object();
synchronized(mutex) {
queue.add(o);
while(true) {
if(!writer && o == queue.get(0)) {
if(w) {
if(readers == 0) {
writer = true;
break;
}
} else if(readers < Math.max(ctx.mprop.num(MainProp.PARALLEL), 1)) {
++readers;
break;
}
}
try {
mutex.wait();
} catch(final InterruptedException ex) {
Util.stack(ex);
}
}
queue.remove(0);
}
}
/**
* Modifications after executing a command.
* @param w writing flag
*/
void unlock(final boolean w) {
synchronized(mutex) {
if(w) {
writer = false;
} else {
--readers;
}
mutex.notifyAll();
}
}
}