001: /*
002: * HA-JDBC: High-Availability JDBC
003: * Copyright (c) 2004-2007 Paul Ferraro
004: *
005: * This library is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU Lesser General Public License as published by the
007: * Free Software Foundation; either version 2.1 of the License, or (at your
008: * option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
013: * for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public License
016: * along with this library; if not, write to the Free Software Foundation,
017: * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * Contact: ferraro@users.sourceforge.net
020: */
021: package net.sf.hajdbc.local;
022:
023: import java.util.HashMap;
024: import java.util.Map;
025: import java.util.concurrent.TimeUnit;
026: import java.util.concurrent.locks.Condition;
027: import java.util.concurrent.locks.Lock;
028: import java.util.concurrent.locks.ReadWriteLock;
029:
030: import net.sf.hajdbc.LockManager;
031: import net.sf.hajdbc.util.concurrent.SemaphoreReadWriteLock;
032:
033: /**
034: * @author Paul Ferraro
035: */
036: public class LocalLockManager implements LockManager {
037: private Map<String, ReadWriteLock> lockMap = new HashMap<String, ReadWriteLock>();
038:
039: /**
040: * @see net.sf.hajdbc.LockManager#readLock(java.lang.String)
041: */
042: @Override
043: public Lock readLock(String object) {
044: Lock lock = this .getReadWriteLock(null).readLock();
045:
046: return (object == null) ? lock : new GlobalLock(lock, this
047: .getReadWriteLock(object).readLock());
048: }
049:
050: /**
051: * @see net.sf.hajdbc.LockManager#writeLock(java.lang.String)
052: */
053: @Override
054: public Lock writeLock(String object) {
055: ReadWriteLock readWriteLock = this .getReadWriteLock(null);
056:
057: return (object == null) ? readWriteLock.writeLock()
058: : new GlobalLock(readWriteLock.readLock(), this
059: .getReadWriteLock(object).writeLock());
060: }
061:
062: private synchronized ReadWriteLock getReadWriteLock(String object) {
063: ReadWriteLock lock = this .lockMap.get(object);
064:
065: if (lock == null) {
066: lock = new SemaphoreReadWriteLock();
067:
068: this .lockMap.put(object, lock);
069: }
070:
071: return lock;
072: }
073:
074: private static class GlobalLock implements Lock {
075: private Lock globalLock;
076: private Lock lock;
077:
078: GlobalLock(Lock globalLock, Lock lock) {
079: this .globalLock = globalLock;
080: this .lock = lock;
081: }
082:
083: @Override
084: public void lock() {
085: this .globalLock.lock();
086: this .lock.lock();
087: }
088:
089: @Override
090: public void lockInterruptibly() throws InterruptedException {
091: this .globalLock.lockInterruptibly();
092:
093: try {
094: this .lock.lockInterruptibly();
095: } catch (InterruptedException e) {
096: this .globalLock.unlock();
097: throw e;
098: }
099: }
100:
101: @Override
102: public boolean tryLock() {
103: if (this .globalLock.tryLock()) {
104: if (this .lock.tryLock()) {
105: return true;
106: }
107:
108: this .globalLock.unlock();
109: }
110:
111: return false;
112: }
113:
114: @Override
115: public boolean tryLock(long time, TimeUnit unit)
116: throws InterruptedException {
117: if (this .globalLock.tryLock(time, unit)) {
118: if (this .lock.tryLock(time, unit)) {
119: return true;
120: }
121:
122: this .globalLock.unlock();
123: }
124:
125: return false;
126: }
127:
128: @Override
129: public void unlock() {
130: this .lock.unlock();
131: this .globalLock.unlock();
132: }
133:
134: @Override
135: public Condition newCondition() {
136: throw new UnsupportedOperationException();
137: }
138: }
139:
140: /**
141: * @see net.sf.hajdbc.LockManager#start()
142: */
143: @Override
144: public void start() throws Exception {
145: // Do nothing
146: }
147:
148: /**
149: * @see net.sf.hajdbc.LockManager#stop()
150: */
151: @Override
152: public void stop() {
153: // Do nothing
154: }
155: }
|