aboutsummaryrefslogtreecommitdiffstats
path: root/archiva-modules/archiva-base/archiva-filelock
diff options
context:
space:
mode:
authorMartin Stockhammer <martin_s@apache.org>2017-05-28 22:32:29 +0200
committerMartin Stockhammer <martin_s@apache.org>2017-05-28 22:40:07 +0200
commit878287b7b3a8c42a4a78028ca4d7b5204b4a5ab8 (patch)
tree062c2ec4779d34a41b72040ce67874f6a8a57050 /archiva-modules/archiva-base/archiva-filelock
parent2d23c4a7f038ad3a0cb8b2135b8aa695e0395514 (diff)
downloadarchiva-878287b7b3a8c42a4a78028ca4d7b5204b4a5ab8.tar.gz
archiva-878287b7b3a8c42a4a78028ca4d7b5204b4a5ab8.zip
[MRM-1945] Fixing race condition
Do not return used locks anymore. If the lock map contains an entry already, the retry loop continues.
Diffstat (limited to 'archiva-modules/archiva-base/archiva-filelock')
-rw-r--r--archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java59
-rw-r--r--archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java20
2 files changed, 57 insertions, 22 deletions
diff --git a/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java b/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java
index ee4fb35be..dcfeb04b3 100644
--- a/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java
+++ b/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java
@@ -71,6 +71,8 @@ public class DefaultFileLockManager
while ( !acquired )
{
+ // Make sure that not a bad lock is returned, if a exception was thrown.
+ lock = null;
if ( timeout > 0 )
{
@@ -88,7 +90,7 @@ public class DefaultFileLockManager
if ( current != null )
{
- log.debug( "read lock file exist continue wait" );
+ log.trace( "read lock file exist continue wait" );
continue;
}
@@ -97,7 +99,22 @@ public class DefaultFileLockManager
lock = new Lock( file, false );
createNewFileQuietly( file );
lock.openLock( false, timeout > 0 );
- acquired = true;
+ // We are not returning an existing lock. If the lock is not
+ // exclusive, another thread may release the lock and the client
+ // knows nothing about it.
+ // The only atomic operation is the putIfAbsent operation, so if
+ // this returns null everything is OK, otherwise we should start at
+ // the beginning.
+ current = lockFiles.putIfAbsent( file, lock );
+ if ( current == null )
+ {
+ // Success
+ acquired = true;
+ } else {
+ // We try again
+ lock.close();
+ lock=null;
+ }
}
catch ( FileNotFoundException e )
{
@@ -116,14 +133,10 @@ public class DefaultFileLockManager
}
catch ( IllegalStateException e )
{
- log.debug( "openLock {}:{}", e.getClass(), e.getMessage() );
+ log.trace( "openLock {}:{}", e.getClass(), e.getMessage() );
}
}
- Lock current = lockFiles.putIfAbsent( file, lock );
- if ( current != null )
- {
- lock = current;
- }
+
return lock;
}
@@ -149,7 +162,8 @@ public class DefaultFileLockManager
while ( !acquired )
{
-
+ // Make sure that not a bad lock is returned, if a exception was thrown.
+ lock = null;
if ( timeout > 0 )
{
long delta = stopWatch.getTime();
@@ -169,14 +183,29 @@ public class DefaultFileLockManager
if ( current != null )
{
- log.debug( "write lock file exist continue wait" );
+ log.trace( "write lock file exist continue wait" );
continue;
}
lock = new Lock( file, true );
createNewFileQuietly( file );
lock.openLock( true, timeout > 0 );
- acquired = true;
+ // We are not returning an existing lock. If the lock is not
+ // exclusive, another thread may release the lock and the client
+ // knows nothing about it.
+ // The only atomic operation is the putIfAbsent operation, so if
+ // this returns null everything is OK, otherwise we should start at
+ // the beginning.
+ current = lockFiles.putIfAbsent( file, lock );
+ if ( current == null )
+ {
+ // Success
+ acquired = true;
+ } else {
+ // We try again
+ lock.close();
+ lock=null;
+ }
}
catch ( FileNotFoundException e )
{
@@ -195,16 +224,10 @@ public class DefaultFileLockManager
}
catch ( IllegalStateException e )
{
- log.debug( "openLock {}:{}", e.getClass(), e.getMessage() );
+ log.trace( "openLock {}:{}", e.getClass(), e.getMessage() );
}
}
- Lock current = lockFiles.putIfAbsent( file, lock );
- if ( current != null )
- {
- lock = current;
- }
-
return lock;
diff --git a/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java b/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java
index 7fa30b566..af189ba49 100644
--- a/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java
+++ b/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java
@@ -144,11 +144,14 @@ public class DefaultFileLockManagerTest {
try {
logger.info("thread3");
Lock lock = fileLockManager.readFileLock(this.file);
+ Path outFile = null;
try {
+ outFile = Files.createTempFile("foo", ".jar");
Files.copy(Paths.get(lock.getFile().getPath()),
- new FileOutputStream(File.createTempFile("foo", ".jar")));
+ Files.newOutputStream(outFile));
} finally {
fileLockManager.release(lock);
+ if (outFile!=null) Files.delete( outFile );
}
logger.info("thread3 ok");
success.incrementAndGet();
@@ -207,10 +210,13 @@ public class DefaultFileLockManagerTest {
try {
logger.info("thread6");
Lock lock = fileLockManager.readFileLock(this.file);
+ Path outFile = null;
try {
- Files.copy(lock.getFile().toPath(), new FileOutputStream(File.createTempFile("foo", ".jar")));
+ outFile = Files.createTempFile("foo", ".jar");
+ Files.copy(lock.getFile().toPath(), Files.newOutputStream( outFile ));
} finally {
fileLockManager.release(lock);
+ if (outFile!=null) Files.delete( outFile );
}
logger.info("thread6 ok");
success.incrementAndGet();
@@ -248,10 +254,13 @@ public class DefaultFileLockManagerTest {
try {
logger.info("thread8");
Lock lock = fileLockManager.readFileLock(this.file);
+ Path outFile = null;
try {
- Files.copy(lock.getFile().toPath(), new FileOutputStream(File.createTempFile("foo", ".jar")));
+ outFile = Files.createTempFile("foo", ".jar");
+ Files.copy(lock.getFile().toPath(), Files.newOutputStream( outFile ));
} finally {
fileLockManager.release(lock);
+ if (outFile!=null) Files.delete( outFile );
}
logger.info("thread8 ok");
success.incrementAndGet();
@@ -288,10 +297,13 @@ public class DefaultFileLockManagerTest {
try {
logger.info("thread10");
Lock lock = fileLockManager.readFileLock(this.file);
+ Path outFile = null;
try {
- Files.copy(lock.getFile().toPath(), new FileOutputStream(File.createTempFile("foo", ".jar")));
+ outFile = Files.createTempFile("foo", ".jar");
+ Files.copy(lock.getFile().toPath(), Files.newOutputStream( outFile ));
} finally {
fileLockManager.release(lock);
+ if (outFile!=null) Files.delete(outFile);
}
logger.info("thread10 ok");
success.incrementAndGet();