Public Member Functions | |
JvnObjectImpl (Serializable o) | |
void | jvnLockRead () throws JvnException |
void | jvnLockWrite () throws JvnException |
void | jvnUnLock () throws JvnException |
int | jvnGetObjectId () throws JvnException |
void | jvnSetObjectId (int id) throws JvnException |
Serializable | jvnGetObjectState () throws JvnException |
void | jvnInvalidateReader () throws JvnException |
Serializable | jvnInvalidateWriter () throws JvnException |
Serializable | jvnInvalidateWriterForReader () throws JvnException |
Protected Attributes | |
Serializable | __containedObject = null |
Package Attributes | |
JvnObjectState | __containedObjectLockState = null |
Private Attributes | |
int | numberOfReadLocks = -1 |
int | jvnObjectId = -1 |
Static Private Attributes | |
static final long | serialVersionUID = -1348964285294975085L |
Definition at line 17 of file JvnObjectImpl.java.
jvn.JvnObjectImpl.JvnObjectImpl | ( | Serializable | o | ) |
Constructor based on a serializable object. Once constructed, it will also take a write lock on the object. NOTE: removed "throws JvnException" because there's nothing that could trigger it, and most of all, it wreaks havoc in Jvn2: * this exception cannot be caught, as the call to another constructor (from super or this) must be the first instruction in a constructor... * judging from the example, JvnException is not supposed to be thrown by the Jvn* constructors.
Definition at line 71 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.__containedObject, jvn.JvnObjectImpl.__containedObjectLockState, and jvn.JvnObjectImpl.numberOfReadLocks.
00071 { 00072 __containedObject = o; 00073 numberOfReadLocks = 0; 00074 __containedObjectLockState = JvnObjectState.STATE_WLOCKT; 00075 }
void jvn.JvnObjectImpl.jvnLockRead | ( | ) | throws JvnException |
Obtains a read lock on the Javanaise object:
TODO: Read lock requests should wait if some write locks or unlocks are pending, otherwise we risk starvation. Note that the wait also needs to be propagated to the Javanaise Coordinator as well as all the other Javanaise servers that have a read lock on the Javanaise object.
Implements jvn.JvnObject.
Definition at line 92 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.__containedObject, jvn.JvnObjectImpl.__containedObjectLockState, jvn.JvnObjectImpl.jvnObjectId, and jvn.JvnObjectImpl.numberOfReadLocks.
00092 { 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 }
void jvn.JvnObjectImpl.jvnLockWrite | ( | ) | throws JvnException |
Obtains a write lock on the Javanaise object:
Implements jvn.JvnObject.
Definition at line 144 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.__containedObject, jvn.JvnObjectImpl.__containedObjectLockState, and jvn.JvnObjectImpl.jvnObjectId.
00144 { 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 }
void jvn.JvnObjectImpl.jvnUnLock | ( | ) | throws JvnException |
Unlocks the current lock, whether read or write.
Unlocking a locking doesn't necessarily generate a call on the Javanaise Server or Coordinator. It will probably generate one if requests are pending.
Implements jvn.JvnObject.
Definition at line 194 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.__containedObjectLockState, and jvn.JvnObjectImpl.numberOfReadLocks.
Referenced by irc.IrcJvn2.main(), and counter.CounterJvn2.main().
00194 { 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 }
int jvn.JvnObjectImpl.jvnGetObjectId | ( | ) | throws JvnException |
Gets the Javanaise Object ID.
Implements jvn.JvnObject.
Definition at line 226 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.jvnObjectId.
00226 { 00227 if( jvnObjectId <= 0 ) { 00228 throw new JvnException("Current Javanaise Object ID is invalid!"); 00229 } else { 00230 return jvnObjectId; 00231 } 00232 }
void jvn.JvnObjectImpl.jvnSetObjectId | ( | int | id | ) | throws JvnException |
Sets the Javanaise Object ID.
id | : The Javanaise Object ID. |
Implements jvn.JvnObject.
Definition at line 239 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.jvnObjectId.
00239 { 00240 if( id <= 0 ) { 00241 throw new JvnException("Invalid Javanaise Object ID!"); 00242 } else { 00243 jvnObjectId = id; 00244 } 00245 }
Serializable jvn.JvnObjectImpl.jvnGetObjectState | ( | ) | throws JvnException |
Gets the current state of the Javanaise Object. Note that the programmer is responsible for doing a read or write lock before calling this method.
Implements jvn.JvnObject.
Definition at line 256 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.__containedObject, and jvn.JvnObjectImpl.__containedObjectLockState.
00256 { 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 }
void jvn.JvnObjectImpl.jvnInvalidateReader | ( | ) | throws JvnException |
Invalidates a read lock. Once this method has finished, the object lock state is JvnObjectState.STATE_NOLOCK
This is normally called by the Javanaise Server, itself propagating a call received from the Javanaise Coordinator.
Implements jvn.JvnObject.
Definition at line 272 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.__containedObjectLockState.
00272 { 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 }
Serializable jvn.JvnObjectImpl.jvnInvalidateWriter | ( | ) | throws JvnException |
Invalidates a write lock. Once this method has finished, the object lock state is JvnObjectState.STATE_NOLOCK
This is normally called by the Javanaise Server, itself propagating a call received from the Javanaise Coordinator.
Implements jvn.JvnObject.
Definition at line 309 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.__containedObject, and jvn.JvnObjectImpl.__containedObjectLockState.
00309 { 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 }
Serializable jvn.JvnObjectImpl.jvnInvalidateWriterForReader | ( | ) | throws JvnException |
Invalidates a write lock and transforms the lock into a read lock. Once this method has finished, the object lock state is JvnObjectState.STATE_NOLOCK
This is normally called by the Javanaise Server, itself propagating a call received from the Javanaise Coordinator.
Implements jvn.JvnObject.
Definition at line 348 of file JvnObjectImpl.java.
References jvn.JvnObjectImpl.__containedObject, and jvn.JvnObjectImpl.__containedObjectLockState.
00348 { 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 }
final long jvn.JvnObjectImpl.serialVersionUID = -1348964285294975085L [static, private] |
Automatically generated serial version ID
Definition at line 21 of file JvnObjectImpl.java.
Serializable jvn.JvnObjectImpl.__containedObject = null [protected] |
Content of the object. private -> protected for Jvn2.
Definition at line 29 of file JvnObjectImpl.java.
Referenced by jvn.JvnObjectImpl.jvnGetObjectState(), jvn.JvnObjectImpl.jvnInvalidateWriter(), jvn.JvnObjectImpl.jvnInvalidateWriterForReader(), jvn.JvnObjectImpl.jvnLockRead(), jvn.JvnObjectImpl.jvnLockWrite(), jvn.JvnObjectImpl.JvnObjectImpl(), irc.JvnSentence.JvnRead(), counter.JvnIntegerWrapper.JvnRead(), irc.JvnSentence.JvnWrite(), and counter.JvnIntegerWrapper.JvnWrite().
JvnObjectState jvn.JvnObjectImpl.__containedObjectLockState = null [package] |
Lock state of the object.
Note that the JvnObjectImpl#jvnLockRead() and JvnObjectImpl#jvnLockWrite() methods synchronize using this member in order to have only one request at a time.
We need to do it this way (and not the inverse, say synchronize on this object for all methods accessing this members and synchronize on JvnObjectImpl to have one request at a time) otherwise we get some IllegalMonitorStateException and therefore need weird additional synchronize calls everywhere...
Definition at line 44 of file JvnObjectImpl.java.
Referenced by jvn.JvnObjectImpl.jvnGetObjectState(), jvn.JvnObjectImpl.jvnInvalidateReader(), jvn.JvnObjectImpl.jvnInvalidateWriter(), jvn.JvnObjectImpl.jvnInvalidateWriterForReader(), jvn.JvnObjectImpl.jvnLockRead(), jvn.JvnObjectImpl.jvnLockWrite(), jvn.JvnObjectImpl.JvnObjectImpl(), and jvn.JvnObjectImpl.jvnUnLock().
int jvn.JvnObjectImpl.numberOfReadLocks = -1 [private] |
Number of read locks pending on the local server.
Definition at line 49 of file JvnObjectImpl.java.
Referenced by jvn.JvnObjectImpl.jvnLockRead(), jvn.JvnObjectImpl.JvnObjectImpl(), and jvn.JvnObjectImpl.jvnUnLock().
int jvn.JvnObjectImpl.jvnObjectId = -1 [private] |
Object ID of the Javanaise object.
Definition at line 58 of file JvnObjectImpl.java.
Referenced by jvn.JvnObjectImpl.jvnGetObjectId(), jvn.JvnObjectImpl.jvnLockRead(), jvn.JvnObjectImpl.jvnLockWrite(), and jvn.JvnObjectImpl.jvnSetObjectId().