001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.store;
018    
019    import org.apache.activemq.broker.AbstractLocker;
020    import org.apache.activemq.util.LockFile;
021    import org.apache.activemq.util.ServiceStopper;
022    import org.slf4j.Logger;
023    import org.slf4j.LoggerFactory;
024    
025    import java.io.File;
026    import java.io.IOException;
027    
028    /**
029     * Represents an exclusive lock on a database to avoid multiple brokers running
030     * against the same logical database.
031     *
032     * @org.apache.xbean.XBean element="shared-file-locker"
033     *
034     */
035    public class SharedFileLocker extends AbstractLocker {
036    
037        public static final File DEFAULT_DIRECTORY = new File("KahaDB");
038        private static final Logger LOG = LoggerFactory.getLogger(SharedFileLocker.class);
039    
040        private LockFile lockFile;
041        protected File directory = DEFAULT_DIRECTORY;
042    
043        @Override
044        public void doStart() throws Exception {
045            if (lockFile == null) {
046                File lockFileName = new File(directory, "lock");
047                lockFile = new LockFile(lockFileName, true);
048                if (failIfLocked) {
049                    lockFile.lock();
050                } else {
051                    boolean locked = false;
052                    while ((!isStopped()) && (!isStopping())) {
053                        try {
054                            lockFile.lock();
055                            locked = true;
056                            break;
057                        } catch (IOException e) {
058                            LOG.info("Database "
059                                    + lockFileName
060                                    + " is locked... waiting "
061                                    + (lockAcquireSleepInterval / 1000)
062                                    + " seconds for the database to be unlocked. Reason: "
063                                    + e);
064                            try {
065                                Thread.sleep(lockAcquireSleepInterval);
066                            } catch (InterruptedException e1) {
067                            }
068                        }
069                    }
070                    if (!locked) {
071                        throw new IOException("attempt to obtain lock aborted due to shutdown");
072                    }
073                }
074            }
075        }
076    
077        @Override
078        public boolean keepAlive() {
079            return lockFile != null && lockFile.keepAlive();
080        }
081    
082        @Override
083        public void doStop(ServiceStopper stopper) throws Exception {
084            lockFile.unlock();
085            lockFile=null;
086        }
087    
088        public File getDirectory() {
089            return directory;
090        }
091    
092        public void setDirectory(File directory) {
093            this.directory = directory;
094        }
095    
096        @Override
097        public void configure(PersistenceAdapter persistenceAdapter) throws IOException {
098            this.setDirectory(persistenceAdapter.getDirectory());
099        }
100    }