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 */ 017package org.apache.activemq.store; 018 019import org.apache.activemq.broker.AbstractLocker; 020import org.apache.activemq.util.LockFile; 021import org.apache.activemq.util.ServiceStopper; 022import org.slf4j.Logger; 023import org.slf4j.LoggerFactory; 024 025import java.io.File; 026import 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 */ 035public 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 = keepAlive(); 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}