X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Forg%2Fvamsas%2Fclient%2Fsimpleclient%2FClientsFile.java;h=96fa871004c476c75f71b9ad24922d052dd6a359;hb=e15b38a5b95e0aa5b11707728abb539c073fe27c;hp=2a103edacb987d63d9cfb63780e9f766a6c010a6;hpb=0818a34ab0fef16d9459df1ade0112b0f72ec14f;p=vamsas.git diff --git a/src/org/vamsas/client/simpleclient/ClientsFile.java b/src/org/vamsas/client/simpleclient/ClientsFile.java index 2a103ed..96fa871 100644 --- a/src/org/vamsas/client/simpleclient/ClientsFile.java +++ b/src/org/vamsas/client/simpleclient/ClientsFile.java @@ -17,66 +17,20 @@ import java.io.OutputStream; import java.util.Vector; /** - * @author jim Handler for the clientsFile within a vamsas session. + * Handler for the clientsFile within a vamsas session thread. + * @author jim */ -public class ClientsFile { - private File filelist; - +public class ClientsFile extends ListFile { + private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(ClientsFile.class); /** - * number of my client in list (not known at start but used when known to make - * lock) + * number of my client in list - passed back when a client + * is added to list, and used (if valid) for quickly + * looking up presence of client handle in the list. */ private int syncnum = 1; public ClientsFile(File filelist) throws IOException { - this.filelist = filelist; - if (!this.filelist.exists()) - this.filelist.createNewFile(); - } - - private Lock listlock = null; - - /** - * Get a lock for the ClientsFile - * - * @return true if lock was made - */ - protected boolean lockList() { - if (listlock != null && listlock.isLocked()) - return true; - listlock = null; - if (filelist != null) { - if (filelist.exists()) { - // TODO: see if we need to loop-wait for locks or they just block until - // lock is made... - do { - listlock = new Lock(filelist); // TODO: wait around if we can't get the lock. - } while (!listlock.isLocked()); - // listlock = new Lock(filelist); - return listlock.isLocked(); - } - } else - throw new Error( - "org.vamsas.client.simpleclient.ClientsFile.lockList called for non-initialised ClientsFile!"); - - // no lock possible - return false; - } - - /** - * Explicitly release the ClientsFile lock. - * - * @return true if lock was released. - */ - protected void unlockList() { - if (listlock != null) { - - if (listlock.isLocked()) { - listlock.release(); - } - - listlock = null; - } + super(filelist); } /** @@ -86,12 +40,12 @@ public class ClientsFile { * @return list of clients */ private ClientHandle[] retrieveClientHandles() { - if (lockList()) { + if (lockFile()) { try { ClientHandle[] clients=null; - if (this.listlock.rafile.length()>0) { - ObjectInputStream is = new ObjectInputStream(new BufferedInputStream( - new java.io.FileInputStream(filelist))); + if (fileLock.length()>0) { + + ObjectInputStream is = new ObjectInputStream(fileLock.getBufferedInputStream(true)); Object o; o=is.readObject(); if (o!=null) { @@ -99,7 +53,7 @@ public class ClientsFile { clients = (ClientHandle[]) o; } catch (Exception e) { - System.err.println("Garbage in the clientHandle list "+this.filelist); + System.err.println("Garbage in the clientHandle list "+this.sessionFile); } } } @@ -114,18 +68,57 @@ 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() { - if (lockList()) { + if (lockFile()) { ClientHandle[] clients = retrieveClientHandles(); - unlockList(); + unlockFile(); return clients; } 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 (lockFile(extantlock)) { + ClientHandle[] clients = retrieveClientHandles(); + unlockFile(); + return clients; + } + return null; + } + /** + * adds clientHandle me to the clientList under an existing lock extantLock. + * @param me + * @param extantLock + * @return client index in list or 0 if lock was invalid or addClient operation failed. + */ + public int addClient(ClientHandle me, Lock extantLock) { + return addClient(me, true, extantLock); + } + + /** + * adds clientHandle me to the clientList under an existing lock. + * @param me - clientHandle + * @param disambig - if true then add will fail if an identical clientHandle already exists + * @param extantLock - existing lock + * @return client index in list or 0 if addClient (or the lock) failed. + */ + + public int addClient(ClientHandle me, boolean disambig, Lock extantLock) { + if (lockFile(extantLock)) { + syncnum = addClient(me, disambig); + unlockFile(); + return syncnum; + } + return 0; + } + /** * adds the ClientHandle to the list - if it is not unique, then the * ClientHandle object is modified to make it unique in the list. returns the @@ -137,20 +130,21 @@ public class ClientsFile { public int addClient(ClientHandle me) { syncnum = addClient(me, true); - unlockList(); + unlockFile(); return syncnum; } /** * 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 (lockFile(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; @@ -168,9 +162,9 @@ public class ClientsFile { throw new Error("Failed to write new clientList!"); // failed to put the clientList to disk. } } - unlockList(); + unlockFile(); } else { - throw new Error("Couldn't get lock for "+((filelist==null) ? "Unitialised filelist in ClientsFile" : filelist.getAbsolutePath())); + throw new Error("Couldn't get lock for "+((sessionFile==null) ? "Unitialised sessionFile in ClientsFile" : sessionFile.getAbsolutePath())); } } /** @@ -186,7 +180,10 @@ public class ClientsFile { */ protected int addClient(ClientHandle me, boolean disambiguate) { int newclient = 0; - if (lockList()) { + int tries=5; + while (tries-->0 && !lockFile()) + try { Thread.sleep(1); } catch (Exception e){}; + if (lockFile()) { ClientHandle[] clients = retrieveClientHandles(); if (me.getClientUrn()==null) { // TODO: move this into ClientUrn as a standard form method. @@ -226,58 +223,73 @@ public class ClientsFile { } return newclient; } - /** - * safely writes clients array to the file referred to by filelist. + * when set true - get FileNotFoundExceptions on WinXP when writing to locked stream after the backup has been made (via the backupFile method) + */ + boolean backup=false; + /** + * safely writes clients array to the file referred to by sessionFile. * * @param clients * @return true if successful write. Throws Errors otherwise. */ protected boolean putClientList(ClientHandle[] clients) { - if (lockList()) { - File templist = null; - try { - templist = File.createTempFile(filelist.getName(),".old", filelist.getParentFile()); - FileOutputStream tos = new FileOutputStream(templist); - tos.getChannel().transferFrom(listlock.rafile.getChannel(), 0, - listlock.rafile.length()); - tos.close(); - } catch (FileNotFoundException e1) { - System.err.println("Can't create temp file for clientlist"); - e1.printStackTrace(System.err); - } catch (IOException e1) { - System.err - .println("Error when copying content to temp file for clientlist"); - e1.printStackTrace(System.err); - } - if (templist != null) { - try { - listlock.rafile.setLength(0); - ObjectOutputStream os = new ObjectOutputStream( - new BufferedOutputStream(new FileOutputStream(this.filelist))); - os.writeObject(clients); - os.close(); + if (lockFile()) { + File templist=null; + if (!backup || (templist = backupSessionFile()) != null) { + int retries=3; + while (retries-->0) { + try { + ObjectOutputStream os = + new ObjectOutputStream(fileLock.getBufferedOutputStream(true)); + log.debug("About to write "+clients.length+" clientHandles to output stream."); + os.writeObject(clients); + os.close(); // All done - remove the backup. - templist.delete(); + if (backup) + templist.delete(); templist = null; - } catch (Exception e) { - if (templist != null) { + retries=-1; + } catch (Exception e) { System.err - .println("Serious - problems writing to filelist. Backup in " - + templist.getAbsolutePath()); + .println("Serious - problems writing to sessionFile."); + if (retries>0 && templist != null) { + System.err.println("Recovering from Backup in " + + templist.getAbsolutePath()); + templist.renameTo(fileLock.target); + } e.printStackTrace(System.err); } } + if (retries>-2) { + System.err + .println("Serious - problems writing to sessionFile. Giving Up."); + return false; + } } else { throw new Error( "Couldn't create backup of the clientList before writing to it!"); } } else { throw new Error("Could not lock the clientList: " - + ((filelist == null) ? "Unitialized ClientsFile" - : " failed to get lock on " + filelist.getAbsolutePath())); + + ((sessionFile == null) ? "Unitialized ClientsFile" + : " failed to get lock on " + sessionFile.getAbsolutePath())); } // successful! return true; } + + public void clearList() { + if (lockFile()) { + try { + FileOutputStream fout = fileLock.getFileOutputStream(true); + fout.flush(); + fout.close(); + } catch (Exception e) { + throw new Error("Problems trying to clear clientlist!",e); + + } + } + + } }