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.store.kahadb.MessageDatabase;
021 import org.apache.activemq.util.ServiceStopper;
022 import org.apache.kahadb.util.LockFile;
023 import org.slf4j.Logger;
024 import org.slf4j.LoggerFactory;
025
026 import java.io.File;
027 import java.io.IOException;
028
029 /**
030 * Represents an exclusive lock on a database to avoid multiple brokers running
031 * against the same logical database.
032 *
033 * @org.apache.xbean.XBean element="shared-file-locker"
034 *
035 */
036 public class SharedFileLocker extends AbstractLocker {
037
038 private static final Logger LOG = LoggerFactory.getLogger(SharedFileLocker.class);
039
040 private LockFile lockFile;
041 protected File directory = MessageDatabase.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 void doStop(ServiceStopper stopper) throws Exception {
079 lockFile.unlock();
080 lockFile=null;
081 }
082
083 public File getDirectory() {
084 return directory;
085 }
086
087 public void setDirectory(File directory) {
088 this.directory = directory;
089 }
090
091 @Override
092 public void configure(PersistenceAdapter persistenceAdapter) throws IOException {
093 this.setDirectory(persistenceAdapter.getDirectory());
094 }
095 }