001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.core.persist;
028:
029: import java.io.DataInputStream;
030: import java.io.DataOutputStream;
031: import java.io.File;
032: import java.io.FileInputStream;
033: import java.io.FileOutputStream;
034: import java.io.IOException;
035: import java.text.DecimalFormat;
036: import java.text.SimpleDateFormat;
037: import java.util.Date;
038:
039: /**
040: * A file lock.
041: */
042: public class FileMutex {
043: private static final SimpleDateFormat uniqueNameFormat;
044: static {
045: uniqueNameFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
046: }
047:
048: private File uniqueFile;
049: private File commonFile;
050: private long timeout;
051:
052: public FileMutex(File directory, String commonName, long timeout) {
053: this .timeout = timeout;
054: commonFile = new File(directory, commonName);
055: uniqueFile = new File(directory, uniqueNameFormat
056: .format(new Date()));
057: }
058:
059: public void lock() throws IOException {
060: long endTime = System.currentTimeMillis() + timeout;
061: new FileOutputStream(uniqueFile).close(); // No content needed
062: while (!uniqueFile.renameTo(commonFile)) {
063: if (System.currentTimeMillis() > endTime) {
064: unlock(); // Unlock the mutex for the
065: // (apparently dead) other instance
066: continue; // Rename should now work
067: }
068: try {
069: Thread.sleep(5000); // Wait for the other instance to
070: // unlock
071: } catch (InterruptedException ie) {
072: }
073: }
074: }
075:
076: public void unlock() throws IOException {
077: commonFile.delete();
078: }
079:
080: public static void main(String[] args) {
081: String TMP = "/tmp";
082: String SEQ = TMP + "/seq";
083: String PREFIX = TMP + "/";
084: String COMMON = "filemutexlock";
085: String SUFFIX = args[0];
086: DecimalFormat format = new DecimalFormat("00000");
087: FileMutex fm = new FileMutex(new File(TMP), COMMON, 30000L);
088: try {
089: for (int i = 0; i < 1000; i++) {
090: fm.lock();
091: int seq;
092: try {
093: DataInputStream r = new DataInputStream(
094: new FileInputStream(SEQ));
095: try {
096: seq = r.readInt();
097: } finally {
098: r.close();
099: }
100: } catch (IOException ioe) {
101: seq = 0;
102: }
103: String fileName = PREFIX + format.format(seq) + SUFFIX;
104: new FileOutputStream(fileName).close();
105: DataOutputStream o = new DataOutputStream(
106: new FileOutputStream(SEQ));
107: seq++;
108: o.writeInt(seq);
109: o.close();
110: fm.unlock();
111: Thread.sleep(100);
112: }
113: } catch (Exception e) {
114: e.printStackTrace();
115: }
116: }
117: }
|