JvnObjectImpl.java

Go to the documentation of this file.
00001 
00009 package jvn;
00010 
00011 import java.io.Serializable;
00012 
00013 
00017 public class JvnObjectImpl implements JvnObject {
00021         private static final long serialVersionUID = -1348964285294975085L;
00022 
00029         protected Serializable __containedObject = null;
00030 
00044         JvnObjectState __containedObjectLockState = null;
00045 
00049         private int numberOfReadLocks = -1;
00050 
00058         private int jvnObjectId = -1;
00059 
00071         public JvnObjectImpl( Serializable o ) /*throws JvnException*/ {
00072                 __containedObject = o;
00073                 numberOfReadLocks = 0;
00074                 __containedObjectLockState = JvnObjectState.STATE_WLOCKT;
00075         }
00076 
00092         public void jvnLockRead() throws JvnException {
00093                 // Only process one lock request at a time
00094                 synchronized(__containedObjectLockState) {
00095                         // Whether we should ask the server for the read lock or not
00096                         // Asking needs to be done OUTSIDE a synchronized block (deadlock)
00097                         boolean askServer = false;
00098 
00099                         synchronized(this) {
00100                                 if( __containedObjectLockState == JvnObjectState.STATE_RLOCKC ) {
00101                                         // We already have a cached read lock
00102                                         numberOfReadLocks = 1;
00103                                         __containedObjectLockState = JvnObjectState.STATE_RLOCKT;
00104 //                                      System.out.println("Read lock: upgrading from \"cached\" to \"taken\".");
00105                                 } else if( __containedObjectLockState == JvnObjectState.STATE_RLOCKT ) {
00106                                         // We already have a lock: simply increment reference count
00107                                         numberOfReadLocks++;
00108 //                                      System.out.println("Read lock: one more reader (total: "+numberOfReadLocks+")");
00109                                 } else {
00110                                         // We don't have any read lock, ask the server
00111 //                                      System.out.println("Read lock: obtaining via server");
00112                                         askServer = true;
00113                                 }
00114                         }
00115 
00116                         // Ask the server if needed
00117                         if(askServer){
00118                                 Serializable temp = JvnServerImpl.jvnGetServer().jvnLockRead(jvnObjectId);
00119 
00120                                 // Ask server OK, now resync and update datum
00121                                 synchronized(this) {
00122                                         if(temp==null) {
00123                                                 throw new JvnException("Invalid object received when asking for read lock!");
00124                                         } else {
00125                                                 numberOfReadLocks = 1;
00126                                                 __containedObject = temp;
00127                                                 __containedObjectLockState = JvnObjectState.STATE_RLOCKT;
00128 //                                              System.out.println("Read lock: obtained via server");
00129                                         }
00130                                 }
00131                         }
00132                 }
00133         }
00134 
00144         public void jvnLockWrite() throws JvnException {
00145                 // Only process one lock request at a time
00146                 synchronized(__containedObjectLockState) {
00147                         // Whether we should ask the server for the write lock or not
00148                         // Asking needs to be done OUTSIDE a synchronized block (deadlock)
00149                         boolean askServer = false;
00150 
00151                         synchronized(this) {
00152                                 if( __containedObjectLockState == JvnObjectState.STATE_WLOCKC ) {
00153                                         // We already have a write lock cached
00154                                         __containedObjectLockState = JvnObjectState.STATE_WLOCKT;
00155 //                                      System.out.println("Write lock: upgrading from \"cached\" to \"taken\".");
00156                                 } else {
00157                                         // The server will contact the coordinator if required
00158 //                                      System.out.println("Write lock: obtaining via server");
00159                                         askServer = true;
00160                                 }
00161                         }
00162 
00163                         // Ask the server if needed
00164                         if(askServer) {
00165                                 Serializable temp = JvnServerImpl.jvnGetServer().jvnLockWrite(jvnObjectId);
00166 
00167                                 // Ask server OK, now resync and update datum
00168                                 synchronized(this) {
00169                                         if( temp!=null ) {
00170                                                 __containedObject = temp;
00171                                                 __containedObjectLockState = JvnObjectState.STATE_WLOCKT;
00172 //                                              System.out.println("Write lock: obtained via server");
00173                                         } else {
00174                                                 throw new JvnException("Invalid object received when asking for write lock!");
00175                                         }
00176                                 }
00177                         }
00178                 }
00179         }
00180 
00194         public void jvnUnLock() throws JvnException {
00195                 synchronized(this)
00196                 {
00197                         // Perform the change locally: see "Cohérence: cas de figure 1".
00198                         if (__containedObjectLockState == JvnObjectState.STATE_WLOCKT) {
00199                                 __containedObjectLockState = JvnObjectState.STATE_WLOCKC;
00200 //                              System.out.println("Write lock: downgrading from \"taken\" to \"cached\".");
00201 
00202                                 // Wake threads that are lazily sleeping.
00203                                 this.notifyAll();
00204                         } else if (__containedObjectLockState == JvnObjectState.STATE_RLOCKT) {
00205                                 numberOfReadLocks--;
00206 //                              System.out.println("Read lock: one less reader (total: "+numberOfReadLocks+")");
00207 
00208                                 if( numberOfReadLocks <= 0 ) {
00209                                         // No more read locks left: set lock status as "read lock
00210                                         // cached" and notify people that are waiting
00211 //                                      System.out.println("Read lock: downgrading from \"taken\" to \"cached\".");
00212                                         __containedObjectLockState = JvnObjectState.STATE_RLOCKC;
00213                                         this.notifyAll();
00214                                 }
00215                         } else {
00216                                 throw new JvnException("Tried to unlock an object that's not locked !?!");
00217                         }
00218                 }
00219         }
00220 
00226         public int jvnGetObjectId() throws JvnException {
00227                 if( jvnObjectId <= 0 ) {
00228                         throw new JvnException("Current Javanaise Object ID is invalid!");
00229                 } else {
00230                         return jvnObjectId;
00231                 }
00232         }
00233 
00239         public void jvnSetObjectId(int id) throws JvnException {
00240                 if( id <= 0 ) {
00241                         throw new JvnException("Invalid Javanaise Object ID!");
00242                 } else {
00243                         jvnObjectId = id;
00244                 }
00245         }
00246 
00256         public Serializable jvnGetObjectState() throws JvnException {
00257                 if( __containedObjectLockState != JvnObjectState.STATE_RLOCKT &&
00258                         __containedObjectLockState != JvnObjectState.STATE_WLOCKT ) {
00259                         throw new JvnException("Please make sure you obtain a read or write lock BEFORE getting the object state!");
00260                 } else {
00261                         return __containedObject;
00262                 }
00263         }
00264 
00272         public void jvnInvalidateReader() throws JvnException {
00273                 synchronized(this) {
00274                         if( __containedObjectLockState == JvnObjectState.STATE_RLOCKT ) {
00275 //                              System.out.println("Invalidating reader: current state is \"taken\" ("+numberOfReadLocks+" readers).");
00276                                 try {
00277                                         // Wait while not ready.
00278                                         while( __containedObjectLockState == JvnObjectState.STATE_RLOCKT ) {
00279                                                 this.wait();
00280                                         }
00281                                 } catch (InterruptedException e) {
00282                                         throw new JvnException( "InterruptedException has occured while invalidating reader!\n" + e);
00283                                 }
00284 
00285                                 __containedObjectLockState = JvnObjectState.STATE_NOLOCK;
00286                         } else if( __containedObjectLockState == JvnObjectState.STATE_RLOCKC ) {
00287 //                              System.out.println("Invalidating reader: current state is \"cached\".");
00288                                 __containedObjectLockState = JvnObjectState.STATE_NOLOCK;
00289                         } else {
00290                                 // Don't throw this: we sometimes have some small sync issues
00291                                 // for states (duplicate messages are sent), but it's ignorable
00292 //                              throw new JvnException( "Tried to invalidate a reader but object state is not a reading state, it is: " + __containedObjectLockState );
00293                         }
00294 
00295 //                      System.out.println("Reader invalidation OK: current state is \"no lock\".");
00296                 }
00297         }
00298 
00309         public Serializable jvnInvalidateWriter() throws JvnException {
00310                 synchronized(this) {
00311                         if( __containedObjectLockState == JvnObjectState.STATE_WLOCKT ) {
00312 //                              System.out.println("Invalidating writer: current state is \"taken\".");
00313                                 try {
00314                                         // Wait while not ready.
00315                                         while( __containedObjectLockState == JvnObjectState.STATE_WLOCKT ) {
00316                                                 this.wait();
00317                                         }
00318                                 } catch (InterruptedException e) {
00319                                         throw new JvnException( "InterruptedException has occured while invalidating writer!\n" + e);
00320                                 }
00321 
00322                                 __containedObjectLockState = JvnObjectState.STATE_NOLOCK;
00323                         } else if( __containedObjectLockState == JvnObjectState.STATE_WLOCKC ) {
00324 //                              System.out.println("Invalidating writer: current state is \"cached\".");
00325                                 __containedObjectLockState = JvnObjectState.STATE_NOLOCK;
00326                         } else {
00327                                 // Don't throw this: we sometimes have some small sync issues
00328                                 // for states (duplicate messages are sent), but it's ignorable
00329 //                              throw new JvnException( "Tried to invalidate a writer but object state is not a writing state, it is: " + __containedObjectLockState );
00330                         }
00331 
00332 //                      System.out.println("Writer invalidation OK: current state is \"no lock\".");
00333                         return __containedObject;
00334                 }
00335         }
00336 
00348         public Serializable jvnInvalidateWriterForReader() throws JvnException {
00349                 synchronized(this) {
00350                         if( __containedObjectLockState == JvnObjectState.STATE_WLOCKT ) {
00351 //                              System.out.println("Invalidating writer for reader: current state is \"write lock taken\".");
00352                                 try {
00353                                         // Wait while not ready.
00354                                         while( __containedObjectLockState == JvnObjectState.STATE_WLOCKT ) {
00355                                                 this.wait();
00356                                         }
00357                                 } catch (InterruptedException e) {
00358                                         throw new JvnException( "InterruptedException has occured while invalidating writer for reader!\n" + e);
00359                                 }
00360 
00361                                 __containedObjectLockState = JvnObjectState.STATE_RLOCKC;
00362                         } else if( __containedObjectLockState == JvnObjectState.STATE_WLOCKC ) {
00363 //                              System.out.println("Invalidating writer for reader: current state is \"write lock cached\".");
00364                                 __containedObjectLockState = JvnObjectState.STATE_RLOCKC;
00365                         } else {
00366                                 // Don't throw this: we sometimes have some small sync issues
00367                                 // for states (duplicate messages are sent), but it's ignorable
00368 //                              throw new JvnException( "Tried to invalidate a writer but object state is not a writing state, it is: " + __containedObjectLockState );
00369                         }
00370 
00371 //                      System.out.println("Writer invalidation OK: current state is \"read lock cached\".");
00372                         return __containedObject;
00373                 }
00374         }
00375 }

Generated on Wed Jan 2 10:15:54 2008 for Javanaise by  doxygen 1.5.4