<commit_before>/*
  File: ReentrantLock.java

  Originally written by <NAME> and released into the public domain.
  This may be used for any purposes whatsoever without acknowledgment.
  Thanks for the assistance and support of Sun Microsystems Labs,
  and everyone contributing, testing, and using this code.

*/

package org.exist.storage.lock;

import java.util.Stack;

import org.apache.log4j.Logger;
import org.exist.util.LockException;

/**
 * A lock with the same semantics as builtin
 * Java synchronized locks: Once a thread has a lock, it
 * can re-obtain it any number of times without blocking.
 * The lock is made available to other threads when
 * as many releases as acquires have occurred.
 * 
 * The lock has a timeout: a read lock will be released if the
 * timeout is reached.
*/

public class ReentrantReadWriteLock implements Lock {

    private final static Logger LOG = Logger.getLogger(ReentrantReadWriteLock.class);

    protected String id_ = null;
	protected Thread owner_ = null;
	protected long holds_ = 0;
	public int mode_ = Lock.NO_LOCK;
	private long timeOut_ = 240000L;
	private Stack modeStack = new Stack();
	private int writeLocks = 0;

	public ReentrantReadWriteLock(String id) {
		id_ = id;
	}
	
	/* @deprecated Use other method
	 * @see org.exist.storage.lock.Lock#acquire()
	 */
	public boolean acquire() throws LockException {
		return acquire(Lock.READ_LOCK);
	}

	public boolean acquire(int mode) throws LockException {
		if (mode == Lock.NO_LOCK) {
			LOG.warn("acquired with no lock !");
			return true;
		}
		if (Thread.interrupted())
			throw new LockException();
		Thread caller = Thread.currentThread();
		synchronized (this) {
			if (caller == owner_) {
				++holds_;
				modeStack.push(new Integer(mode));
				if (mode == Lock.WRITE_LOCK)
					writeLocks++;
				mode_ = mode;
//				System.out.println("thread " + caller.getName() + " acquired lock on " + id_ +
//					"; locks held = " + holds_);
				return true;
			} else if (owner_ == null) {
				owner_ = caller;
				holds_ = 1;
				modeStack.push(new Integer(mode));
				if (mode== Lock.WRITE_LOCK)
					writeLocks++;
				mode_ = mode;
//				System.out.println("thread " + caller.getName() + " acquired lock on " + id_);
				return true;
			} else {
				long waitTime = timeOut_;
				long start = System.currentTimeMillis();
				try {
					for (;;) {
						wait(waitTime);
						if (caller == owner_) {
							++holds_;
							modeStack.push(new Integer(mode));
							if (mode == Lock.WRITE_LOCK)
								writeLocks++;
							mode_ = mode;
//							System.out.println("thread " + caller.getName() + " acquired lock on " + id_ +
//								"; locks held = " + holds_);
							return true;
						} else if (owner_ == null) {
							owner_ = caller;
							holds_ = 1;
							modeStack.push(new Integer(mode));
							if (mode == Lock.WRITE_LOCK)
								writeLocks++;
							mode_ = mode;
//							System.out.println("thread " + caller.getName() + " acquired lock on " + id_ +
//								"; locks held = " + holds_);
							return true;
						} else {
							waitTime = timeOut_ - (System.currentTimeMillis() - start);
							if (waitTime <= 0) {
								// blocking thread found: if the lock is read only, remove it
								if (writeLocks == 0) {
									System.out.println("releasing blocking thread " + owner_.getName());
									owner_ = caller;
									while (!modeStack.isEmpty()) {
								    	Integer top = (Integer)modeStack.peek();
								    	top = null;
									}
									holds_ = 1;
									modeStack.push(new Integer(mode));
									mode_ = mode;
//									System.out.println("thread " + caller.getName() + " acquired lock on " + id_ +
//										"; locks held = " + holds_);
									return true;
								} else
									throw new LockException("time out while acquiring a lock");
							}
						}
					}
				} catch (InterruptedException ex) {
					notify();
					throw new LockException("interrupted while waiting for lock");
				}
			}
		}
	}

	public boolean attempt(int mode) {
		Thread caller = Thread.currentThread();
		synchronized (this) {
			if (caller == owner_) {
				++holds_;
				modeStack.push(new Integer(mode));<commit_msg>Quick and obvious fix to locking code. Not tested though...<commit_after>/*
  File: ReentrantLock.java

  Originally written by <NAME> and released into the public domain.
  This may be used for any purposes whatsoever without acknowledgment.
  Thanks for the assistance and support of Sun Microsystems Labs,
  and everyone contributing, testing, and using this code.

*/

package org.exist.storage.lock;

import java.util.Stack;

import org.apache.log4j.Logger;
import org.exist.util.LockException;

/**
 * A lock with the same semantics as builtin
 * Java synchronized locks: Once a thread has a lock, it
 * can re-obtain it any number of times without blocking.
 * The lock is made available to other threads when
 * as many releases as acquires have occurred.
 * 
 * The lock has a timeout: a read lock will be released if the
 * timeout is reached.
*/

public class ReentrantReadWriteLock implements Lock {

    private final static Logger LOG = Logger.getLogger(ReentrantReadWriteLock.class);

    protected String id_ = null;
	protected Thread owner_ = null;
	protected long holds_ = 0;
	public int mode_ = Lock.NO_LOCK;
	private long timeOut_ = 240000L;
	private Stack modeStack = new Stack();
	private int writeLocks = 0;

	public ReentrantReadWriteLock(String id) {
		id_ = id;
	}
	
	/* @deprecated Use other method
	 * @see org.exist.storage.lock.Lock#acquire()
	 */
	public boolean acquire() throws LockException {
		return acquire(Lock.READ_LOCK);
	}

	public boolean acquire(int mode) throws LockException {
		if (mode == Lock.NO_LOCK) {
			LOG.warn("acquired with no lock !");
			return true;
		}
		if (Thread.interrupted())
			throw new LockException();
		Thread caller = Thread.currentThread();
		synchronized (this) {
			if (caller == owner_) {
				++holds_;
				modeStack.push(new Integer(mode));
				if (mode == Lock.WRITE_LOCK)
					writeLocks++;
				mode_ = mode;
//				System.out.println("thread " + caller.getName() + " acquired lock on " + id_ +
//					"; locks held = " + holds_);
				return true;
			} else if (owner_ == null) {
				owner_ = caller;
				holds_ = 1;
				modeStack.push(new Integer(mode));
				if (mode== Lock.WRITE_LOCK)
					writeLocks++;
				mode_ = mode;
//				System.out.println("thread " + caller.getName() + " acquired lock on " + id_);
				return true;
			} else {
				long waitTime = timeOut_;
				long start = System.currentTimeMillis();
				try {
					for (;;) {
						wait(waitTime);
						if (caller == owner_) {
							++holds_;
							modeStack.push(new Integer(mode));
							if (mode == Lock.WRITE_LOCK)
								writeLocks++;
							mode_ = mode;
//							System.out.println("thread " + caller.getName() + " acquired lock on " + id_ +
//								"; locks held = " + holds_);
							return true;
						} else if (owner_ == null) {
							owner_ = caller;
							holds_ = 1;
							modeStack.push(new Integer(mode));
							if (mode == Lock.WRITE_LOCK)
								writeLocks++;
							mode_ = mode;
//							System.out.println("thread " + caller.getName() + " acquired lock on " + id_ +
//								"; locks held = " + holds_);
							return true;
						} else {
							waitTime = timeOut_ - (System.currentTimeMillis() - start);
							if (waitTime <= 0) {
								// blocking thread found: if the lock is read only, remove it
								if (writeLocks == 0) {
									System.out.println("releasing blocking thread " + owner_.getName());
									owner_ = caller;
									while (!modeStack.isEmpty()) {
								    	Integer top = (Integer)modeStack.pop();
								    	top = null;
									}
									holds_ = 1;
									modeStack.push(new Integer(mode));
									mode_ = mode;
//									System.out.println("thread " + caller.getName() + " acquired lock on " + id_ +
//										"; locks held = " + holds_);
									return true;
								} else
									throw new LockException("time out while acquiring a lock");
							}
						}
					}
				} catch (InterruptedException ex) {
					notify();
					throw new LockException("interrupted while waiting for lock");
				}
			}
		}
	}

	public boolean attempt(int mode) {
		Thread caller = Thread.currentThread();
		synchronized (this) {
			if (caller == owner_) {
				++holds_;
				modeStack.push(new Integer(mode));
{'fraction_non_alphanumeric': 0.11806797853309481, 'fraction_numerical': 0.0033392963625521765, 'mean_word_length': 2.5776450511945392, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5624841', 'n_tokens_mistral': 3298, 'n_tokens_neox': 2478, 'n_words': 778}