Issue #2056: Update FileLocker to handle release of ACQUIRING locks
Change-Id: Id1e0f60390775c4143dbbf25070d2efb9ffe2b23 Former-commit-id:163998df17
[formerlye63f2de395
[formerly 9097197872da18fded96e09d133132872d4dcc27]] Former-commit-id:e63f2de395
Former-commit-id:c15635bccc
This commit is contained in:
parent
c3e9110e32
commit
ba4d97a349
1 changed files with 38 additions and 27 deletions
|
@ -51,6 +51,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 23, 2011 mschenke Initial creation
|
||||
* Apr 12, 2013 1903 rjpeter Fix allocateLock freezing out other lock requests.
|
||||
* May 30, 2013 2056 rjpeter Allow ACQUIRING state to be released.
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -73,6 +74,8 @@ public class FileLocker {
|
|||
|
||||
final List<Object> lockers = new ArrayList<Object>();
|
||||
|
||||
long lockTime = System.currentTimeMillis();
|
||||
|
||||
File lockFile;
|
||||
|
||||
LockState lockState = LockState.ACQUIRING;
|
||||
|
@ -210,6 +213,7 @@ public class FileLocker {
|
|||
// TODO: This is not safe as another thread could have a
|
||||
// read lock and we may clobber the read
|
||||
lock.lockers.add(locker);
|
||||
lock.lockTime = System.currentTimeMillis();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -265,30 +269,24 @@ public class FileLocker {
|
|||
return allocateLock(file, lock);
|
||||
} else if (lock != null) {
|
||||
synchronized (lock) {
|
||||
switch (lock.lockState) {
|
||||
case IN_USE:
|
||||
if ((type == Type.READ)
|
||||
&& (type == lock.lockType)) {
|
||||
// A different waiter grabbed it for
|
||||
// reading, we can read it also
|
||||
lock.lockers.add(locker);
|
||||
return true;
|
||||
} else {
|
||||
long curTime = System.currentTimeMillis();
|
||||
long lastMod = lock.lockFile.lastModified();
|
||||
if ((curTime - lastMod) > MAX_WAIT) {
|
||||
System.err
|
||||
.println("Releasing lock: "
|
||||
+ "Lock has been allocated for "
|
||||
+ ((curTime - lastMod) / 1000)
|
||||
+ "s on file "
|
||||
+ file.getPath());
|
||||
locks.remove(file);
|
||||
}
|
||||
if ((type == Type.READ) && (type == lock.lockType)
|
||||
&& LockState.IN_USE.equals(lock.lockState)) {
|
||||
// A different waiter grabbed it for
|
||||
// reading, we can read it also
|
||||
lock.lockers.add(locker);
|
||||
lock.lockTime = System.currentTimeMillis();
|
||||
return true;
|
||||
} else {
|
||||
long curTime = System.currentTimeMillis();
|
||||
if ((curTime - lock.lockTime) > MAX_WAIT) {
|
||||
System.err
|
||||
.println("Releasing lock: "
|
||||
+ "Lock has been allocated for "
|
||||
+ ((curTime - lock.lockTime) / 1000)
|
||||
+ "s on file "
|
||||
+ file.getPath());
|
||||
locks.remove(file);
|
||||
}
|
||||
break;
|
||||
// ACUIRING - NOOP wait for lock to be acquired
|
||||
// RELEASED - loop again and check if next waiter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -309,6 +307,7 @@ public class FileLocker {
|
|||
try {
|
||||
boolean fileUnlocked = false;
|
||||
LockedFile lock = null;
|
||||
|
||||
// Get the Lock
|
||||
synchronized (locks) {
|
||||
lock = locks.get(file);
|
||||
|
@ -319,7 +318,8 @@ public class FileLocker {
|
|||
}
|
||||
|
||||
synchronized (lock) {
|
||||
if (lock.lockState == LockState.IN_USE) {
|
||||
if ((lock.lockState == LockState.IN_USE)
|
||||
|| lock.lockingThread.equals(Thread.currentThread())) {
|
||||
lock.lockers.remove(locker);
|
||||
|
||||
if (lock.lockers.isEmpty()) {
|
||||
|
@ -370,14 +370,23 @@ public class FileLocker {
|
|||
// Get the lock directory, make sure it is not already taken
|
||||
File parentDir = file.getParentFile();
|
||||
|
||||
// If we can't write to the parent directory of the file we are locking,
|
||||
// can't do any locking
|
||||
if (!parentDir.exists()) {
|
||||
parentDir.mkdirs();
|
||||
}
|
||||
|
||||
// If we can't write to the parent directory of the file we are
|
||||
// locking, can't do any locking
|
||||
if (parentDir.canWrite() == false) {
|
||||
UFStatus.getHandler()
|
||||
.handle(Priority.PROBLEM,
|
||||
"Cannot write to directory: "
|
||||
+ parentDir.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean gotLock = false;
|
||||
File lockFile = new File(parentDir, "." + file.getName() + "_LOCK");
|
||||
|
||||
try {
|
||||
// start with a moderate wait
|
||||
long waitInterval = 100;
|
||||
|
@ -409,8 +418,10 @@ public class FileLocker {
|
|||
"Error obtaining file lock: " + file, e);
|
||||
} finally {
|
||||
synchronized (lock) {
|
||||
long millis = System.currentTimeMillis();
|
||||
lock.lockFile = lockFile;
|
||||
lock.lockFile.setLastModified(System.currentTimeMillis());
|
||||
lock.lockTime = millis;
|
||||
lock.lockFile.setLastModified(millis);
|
||||
lock.lockState = LockState.IN_USE;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue