From: jprocter Date: Mon, 24 Oct 2005 13:32:28 +0000 (+0000) Subject: new fileWatcher method passes lock for changed file back to the caller. X-Git-Tag: Release_0.2~445 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=a0f33613dd310add2b9ece2d170e47cfadef145d;hp=c724c5585a7d245621daee3022f0b10a14ccb3ba;p=vamsas.git new fileWatcher method passes lock for changed file back to the caller. ClientsFile methods extended to take an existing lock as a parameter. git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@75 be28352e-c001-0410-b1a7-c7978e42abec --- diff --git a/src/org/vamsas/client/simpleclient/ClientsFile.java b/src/org/vamsas/client/simpleclient/ClientsFile.java index c624100..e5cbc72 100644 --- a/src/org/vamsas/client/simpleclient/ClientsFile.java +++ b/src/org/vamsas/client/simpleclient/ClientsFile.java @@ -17,7 +17,7 @@ import java.io.OutputStream; import java.util.Vector; /** - * @author jim Handler for the clientsFile within a vamsas session. + * @author jim Handler for the clientsFile within a vamsas session thread. */ public class ClientsFile { private File filelist; @@ -36,14 +36,25 @@ public class ClientsFile { private Lock listlock = null; + protected boolean lockList(Lock extantlock) { + if (listlock!=null && !listlock.isLocked()) { + listlock.release();// tidy up invalid lock + } + listlock=extantlock; + return lockList(); + } /** * Get a lock for the ClientsFile * * @return true if lock was made */ protected boolean lockList() { - if (listlock != null && listlock.isLocked()) - return true; + if (listlock != null) + if (listlock.isLocked()) + return true; + else + // lock failed for some reason. + listlock.release(); listlock = null; if (filelist != null) { if (filelist.exists()) { @@ -72,11 +83,7 @@ public class ClientsFile { */ protected void unlockList() { if (listlock != null) { - - if (listlock.isLocked()) { - listlock.release(); - } - + listlock.release(); listlock = null; } } @@ -116,7 +123,7 @@ public class ClientsFile { return null; } /** - * get the clientList from the file. May return false if lock failed! + * get the clientList from the file. May return null if lock failed! * @return clientList */ public ClientHandle[] retrieveClientList() { @@ -127,6 +134,19 @@ public class ClientsFile { } return null; } + /** + * get list from the locked ClientList. + * @param extantlock + * @return clientList or null if lock failed (or file was empty) + */ + public ClientHandle[] retrieveClientList(Lock extantlock) { + if (lockList(extantlock)) { + ClientHandle[] clients = retrieveClientHandles(); + unlockList(); + return clients; + } + return null; + } /** * adds the ClientHandle to the list - if it is not unique, then the @@ -145,14 +165,15 @@ public class ClientsFile { /** * removes 'me' from the session ClientList without complaint if 'me' isn't in the clientList already. - * @param me + * @param me client handle to be removed + * @param clientlock existing lock passed from watcher. */ - public void removeClient(ClientHandle me) { + public void removeClient(ClientHandle me, Lock clientlock) { int mynum=-1; - if (lockList()) { + if (lockList(clientlock)) { ClientHandle[] clients = retrieveClientHandles(); if (clients != null) { - if (clients[syncnum-1]!=me) { + if ((syncnum<=0 || syncnum>clients.length) || clients[syncnum-1]!=me) { for (int i = 0, j = clients.length; i < j; i++) if (clients[i].equals(me)) { mynum=i; diff --git a/src/org/vamsas/client/simpleclient/FileWatcher.java b/src/org/vamsas/client/simpleclient/FileWatcher.java index bc9f705..34897a8 100644 --- a/src/org/vamsas/client/simpleclient/FileWatcher.java +++ b/src/org/vamsas/client/simpleclient/FileWatcher.java @@ -18,23 +18,29 @@ public class FileWatcher { private long lastStat[]; boolean waslocked=false; boolean exists = false; - /** - * Make a watcher for a particular file. If the file doesn't exist, the - * watcher will watch for its creation (and indicate a change of state) - * For locked files, the removal of a lock constitutes a change of - * state if the file was modified. - * - * @param subject + * transient lock on subject - can be passed back to calling class + * to preserve new state of file for immediate reading. */ + private Lock subjectLock = null; + + private void clearLock() { + if (subjectLock!=null) + subjectLock.release(); + subjectLock=null; + } + private boolean checkLock() { if (subject!=null && subject.exists()) { - Lock tl = new Lock(subject); - if (tl.isLocked()) { - tl.release(); + if (subjectLock!=null) { + subjectLock.release(); + } + subjectLock = new Lock(subject); + if (subjectLock.isLocked()) { + // subjectLock.release(); return false; } - tl.release(); + clearLock(); return true; } return false; @@ -51,7 +57,7 @@ public class FileWatcher { /** * Detect changes in file state and release of any * lock in place during change. - * @return true if file state has changed + * @return true if file state has changed. Leaves lock in subjectLock (ready to be passed to caller) */ private boolean check() { if (subject != null) { @@ -87,6 +93,7 @@ public class FileWatcher { } return false; } + public void setState() { if (subject!=null) { lastStat = getStat(subject); @@ -95,13 +102,41 @@ public class FileWatcher { } } + /** + * Make a watcher for a particular file. If the file doesn't exist, the + * watcher will watch for its creation (and indicate a change of state) + * For locked files, the removal of a lock constitutes a change of + * state if the file was modified. + * + * @param subject + */ + public FileWatcher(File subject) { // TODO Auto-generated constructor stub this.subject = subject; setState(); } - + /** + * Test for change in file state. Only indicates a change + * after any lock on a file has been released. + * @return true if file has been modified. + */ public boolean hasChanged() { - return check(); + boolean res = check(); + clearLock(); + return res; + } + /** + * passes lock back to caller if hasChanged returned true. + * @return + */ + public Lock getChangedState() { + boolean res = check(); + if (res) + return subjectLock; + else { + clearLock(); + return null; + } } } diff --git a/src/org/vamsas/test/simpleclient/ClientsFileTest.java b/src/org/vamsas/test/simpleclient/ClientsFileTest.java index 072a591..a149a16 100644 --- a/src/org/vamsas/test/simpleclient/ClientsFileTest.java +++ b/src/org/vamsas/test/simpleclient/ClientsFileTest.java @@ -7,6 +7,7 @@ import java.util.Vector; import org.vamsas.client.ClientHandle; import org.vamsas.client.simpleclient.ClientsFile; import org.vamsas.client.simpleclient.FileWatcher; +import org.vamsas.client.simpleclient.Lock; public class ClientsFileTest { private static Vector commands; @@ -60,7 +61,7 @@ public class ClientsFileTest { ch=new ClientHandle(args[argc], args[argc+1]); ch.setClientUrn(args[argc+2]); argc+=3; - cfhand.removeClient(ch); + cfhand.removeClient(ch, null); System.out.println("Client removed (apparently)"); break; case 2: @@ -91,8 +92,10 @@ public class ClientsFileTest { // watch FileWatcher w=new FileWatcher(cf); while (cf.exists()) { - if (w.hasChanged()) { - ClientHandle[] cl = cfhand.retrieveClientList(); + // get watcher's lock to ensure state change is fixed for retrieval + Lock chlock=w.getChangedState(); + if (chlock!=null) { + ClientHandle[] cl = cfhand.retrieveClientList(chlock); System.out.println("-- Watching "+cf.getName()); //while (w.hasChanged()) // ;