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.commons.lang.lock;
020
021public final class KeyLock {
022        
023        private final Token token=new Token();
024        private KeyLockListener listener;
025
026        public KeyLock() {
027                this.listener=NullKeyLockListener.getInstance();
028        }
029        public KeyLock(KeyLockListener listener) {
030                this.listener=listener;
031        }
032
033        public void start(String key) {
034                while(true) {
035                        // nobody inside
036                        
037                        synchronized(token) {
038                                if(token.value==null) {
039                                        token.value=key;
040                                        token.count++;
041                                        listener.onStart(token.value,true);      
042                                        return;
043                                }
044                                if(key.equalsIgnoreCase(token.value)) {
045                                        token.count++;
046                                        listener.onStart(token.value,false);      
047                                        return;
048                                }
049                                try {
050                                        token.wait();
051                                } 
052                                catch (InterruptedException e) {}
053                        }
054                }
055        }
056        
057        public void end() {
058                synchronized(token) {
059                        if(--token.count<=0) {
060                                listener.onEnd(token.value,true);    
061                                if(token.count<0)token.count=0;
062                                token.value=null;
063                        }
064                        else listener.onEnd(token.value,false); 
065                        token.notify();
066                }
067        }
068        
069        public void setListener(KeyLockListener listener) { 
070                this.listener=listener;
071        }
072        
073        
074        
075        
076}
077
078class Token {
079        int count=0;
080        String value=null;
081}
082