001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.lock;
020
021import java.util.ArrayList;
022import java.util.List;
023
024import lucee.commons.lock.Lock;
025import lucee.commons.lock.LockException;
026import lucee.commons.lock.LockInterruptedException;
027import lucee.commons.lock.rw.RWKeyLock;
028
029/**
030 * Lock mnager to make a log by a string name
031 */
032public final class LockManagerImpl implements LockManager {
033
034        private static List<LockManagerImpl> managers=new ArrayList<LockManagerImpl>();
035    private RWKeyLock<String> locks=new RWKeyLock<String>();
036        private boolean caseSensitive;
037        
038    private LockManagerImpl(boolean caseSensitive) {
039        this.caseSensitive=caseSensitive;
040    }
041        
042    public static LockManager getInstance(boolean caseSensitive) {
043        LockManagerImpl lmi = new LockManagerImpl(caseSensitive);
044        managers.add(lmi);
045        return lmi;
046    }
047        
048        @Override
049        public LockData lock(int type, String name, int timeout, int pageContextId) throws LockTimeoutException, InterruptedException {
050                if(!caseSensitive)name=name.toLowerCase();
051                //if(type==LockManager.TYPE_READONLY) return new ReadLockData(name,pageContextId);
052                if(timeout<=0)timeout=1;
053                Lock lock;
054                try {
055                        lock=locks.lock(name,timeout,type==LockManager.TYPE_READONLY);
056                } catch (LockException e) {
057                        throw new LockTimeoutException(type,name,timeout);
058                } 
059                catch (LockInterruptedException e) {
060                        throw e.getLockInterruptedException();
061                }
062                
063                return new LockDataImpl(lock,name,pageContextId,type==LockManager.TYPE_READONLY);
064        }
065        
066        public void unlock(LockData data) {
067                Lock l = data.getLock();
068                locks.unlock(l);
069        }
070    
071        @Override
072        public String[] getOpenLockNames() {
073                List<String> list = locks.getOpenLockNames();
074                return list.toArray(new String[list.size()]);
075        }
076
077        @Override
078        public void clean() {
079                locks.clean();
080        }
081
082
083        public Boolean isReadLocked(String name) {
084                if(!caseSensitive)name=name.toLowerCase();
085                return locks.isReadLocked(name);
086        }
087        
088        public Boolean isWriteLocked(String name) {
089                if(!caseSensitive)name=name.toLowerCase();
090                return locks.isWriteLocked(name);
091        }
092        
093        
094}