001package com.hammurapi.store;
002
003import java.util.concurrent.locks.Lock;
004import java.util.concurrent.locks.ReadWriteLock;
005
006/**
007 * This lock acts on behalf of another lock and acquires its own locks
008 * only if the master doesn't hold corresponding locks. This class is used
009 * to distribute store operations to multiple threads/processes.
010 * @author Pavel Vlasov
011 *
012 */
013public class DeputyReadWriteLock implements ReadWriteLock {
014        
015        private DeputyLock readLock;
016        private DeputyLock writeLock;
017        
018        public DeputyReadWriteLock(ReadWriteLock master, boolean readLocked, boolean writeLocked) {
019                this.readLock = new DeputyLock(master.readLock(), readLocked || writeLocked, false, null);
020                this.writeLock = new DeputyLock(master.writeLock(), writeLocked, !writeLocked && readLocked, "Read lock is already held, can't upgrade to write lock, locks can only be downgraded.");
021        }
022        
023        protected DeputyReadWriteLock(DeputyLock readLock, DeputyLock writeLock) {
024                this.readLock = readLock;
025                this.writeLock = writeLock;
026        }
027
028        @Override
029        public Lock readLock() {
030                return readLock;
031        }
032
033        @Override
034        public Lock writeLock() {
035                return writeLock;
036        }
037        
038        public DeputyReadWriteLock createDeputy() {
039                return new DeputyReadWriteLock(this, readLock.isLocked() || writeLock.isLocked(), writeLock.isLocked());
040        }
041
042}