Author: ogusakov Date: Tue Sep 9 19:51:37 2008 New Revision: 693690 URL: http://svn.apache.org/viewvc?rev=693690&view=rev Log: added directory locking mechanism to be used in Local Repository
Added: maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties - copied, changed from r693178, maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties Removed: maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties Modified: maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java Modified: maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java?rev=693690&r1=693689&r2=693690&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java (original) +++ maven/sandbox/trunk/mercury/mercury-it/src/test/java/org/apache/maven/mercury/repository/tests/AbstractRepositoryWriterM2Test.java Tue Sep 9 19:51:37 2008 @@ -104,7 +104,6 @@ artifactBinary = File.createTempFile( "test-repo-writer", "bin" ); FileUtil.writeRawData( artifactBinary, getClass().getResourceAsStream( "/maven-core-2.0.9.jar" ) ); - } @@ -113,11 +112,6 @@ throws Exception { super.tearDown(); -// if( nexusForkedAppBooter != null ) -// { -// nexusForkedAppBooter.stop(); -// nexusForkedAppBooter = null; -// } } public void testWriteArtifact() @@ -226,4 +220,10 @@ assertEquals( 7785, ap.length() ); } + public void testWriteContention() + throws Exception + { + + } + } Modified: maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java?rev=693690&r1=693689&r2=693690&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java (original) +++ maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java Tue Sep 9 19:51:37 2008 @@ -5,11 +5,16 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.channels.OverlappingFileLockException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -44,6 +49,7 @@ */ public class FileUtil { + public static final String LOCK_FILE = ".lock"; public static final String DEFAULT_CHARSET = "utf-8"; public static final int K = 1024; public static final int DEFAULT_BUFFER_SIZE = 10 * K; @@ -678,5 +684,57 @@ } } //--------------------------------------------------------------------------------------------------------------- + /** + * try to acquire lock on specfied directory for <code>millis<code> millis + * + * @param dir directory to lock + * @param millis how long to wait for the lock before surrendering + * @param sleepFor how long to sleep between attempts + * + * @return obtained FileLock or null + * @throws IOException if there were problems obtaining the lock + */ + public static boolean lockDir( String dir, long millis, long sleepFor ) + throws IOException + { + File df = new File(dir); + if( !df.isDirectory() ) + throw new IOException( _lang.getMessage( "file.is.not.directory", dir ) ); + + File lock = new File(dir,LOCK_FILE); + long start = System.currentTimeMillis(); + + for(;;) + try + { + if( lock.exists() ) + throw new OverlappingFileLockException(); + FileOutputStream fos = new FileOutputStream( lock ); + fos.write( 32 ); + fos.flush(); + fos.close(); + + return true; + } + catch( OverlappingFileLockException le ) + { + try { Thread.sleep( sleepFor ); } catch( InterruptedException e ){} + if( System.currentTimeMillis() - start > millis ) + return false; + } + } + //--------------------------------------------------------------------------------------------------------------- + public static void unlockDir( String dir ) + throws IOException + { + File df = new File(dir); + if( !df.isDirectory() ) + throw new IOException( _lang.getMessage( "file.is.not.directory", dir ) ); + + File lock = new File(dir,LOCK_FILE); + if( lock.exists() ) + lock.delete(); + } + //--------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------- } Copied: maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties (from r693178, maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties) URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties?p2=maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties&p1=maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties&r1=693178&r2=693690&rev=693690&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/mercury-util/src/main/resources/org/apache/maven/mercury/util/Messages.properties (original) +++ maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties Tue Sep 9 19:51:37 2008 @@ -16,3 +16,5 @@ file.is.directory=File "{0}" is a folder and no recursive option is specified. Skipping .. no.mandatory.signature=Mandatory signature {1} does not exist for file {0} file.failed.verification=File {0} failed following verifications: {1} + +file.is.not.directory=Specified file {0} is not a directory Modified: maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java?rev=693690&r1=693689&r2=693690&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java (original) +++ maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java Tue Sep 9 19:51:37 2008 @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.nio.channels.FileLock; import java.util.HashSet; import junit.framework.TestCase; @@ -147,4 +148,95 @@ FileUtil.verify( b, vFacs, false, true ); } //---------------------------------------------------------------------------------------- + public void testLock() + throws Exception + { + class TestThread1 + extends Thread + { + boolean lock; + String dir; + + public TestThread1( String dir ) + { + this.dir = dir; + } + @Override + public void run() + { + try + { + lock = FileUtil.lockDir( dir, 1000L, 100L ); + assertTrue( lock ); + System.out.println("Thread1: lock "+dir+" obtained"); + + try { sleep( 2000L ); } catch( InterruptedException e ) {} + System.out.println("Thread1: slept for 2s"); + + FileUtil.unlockDir( dir ); + System.out.println("Thread1: lock "+dir+" released"); + } + catch( Exception e ) + { + fail( e.getMessage() ); + } + } + + } + + class TestThread2 + extends Thread + { + boolean lock; + String dir; + + public TestThread2( String dir ) + { + this.dir = dir; + } + @Override + public void run() + { + try + { + lock = FileUtil.lockDir( dir, 10L, 10L ); + assertFalse( lock ); + System.out.println("Thread2: resource "+dir+" locked"); + + lock = FileUtil.lockDir( dir, 5000L, 100L ); + assertNotNull( lock ); + + FileUtil.unlockDir( dir ); + System.out.println("Thread2: lock "+dir+" released"); + } + catch( Exception e ) + { + fail( e.getMessage() ); + } + } + + } + + File dir = File.createTempFile( "test-", "-dir" ); + String dirName = dir.getAbsolutePath(); + dir.delete(); + dir = new File( dirName ); + dir.mkdir(); + dir.deleteOnExit(); + + TestThread1 th1 = new TestThread1( dirName ); + TestThread2 th2 = new TestThread2( dirName ); + + th1.start(); + th2.start(); + + for(;;) + if( th1.isAlive() || th2.isAlive() ) + Thread.sleep( 1000L ); + else + break; + + System.out.println("Multi-threaded test finished successfully"); + } + //---------------------------------------------------------------------------------------- }