com.surelogic
Annotation Type RegionLock


@Documented
@Target(value=TYPE)
public @interface RegionLock

Declares a new region lock for the class to which this annotation is applied. This declaration creates a new named lock that associates a particular lock object with a region of the class. The region may only be accessed when the lock is held.

To declare more than one lock for a class use the RegionLocks annotation. It is a modeling error for a class to have both a RegionLocks and a RegionLock annotation.

The named lock is a Java object. If the object's type implements java.util.concurrent.locks.Lock then the lock object must be used according to the protocol of the Lock interface. Otherwise, the object must be used as a Java intrinsic lock, i.e., with synchronized blocks.

Semantics:

The program must be holding the lock denoted by the lockExpression when the state specified by the regionName is read or written, unless

The locking policy stated by a RegionLock annotation likely associated with a higher-level invariant. This annotation does not, however, elicit the higher-level invariant from the programmer.

Examples:

A locking policy, named SimpleLock, that indicates that synchronizing on the instance protects the all of the instance's state.
 @RegionLock("SimpleLock is this protects Instance")
 class Simple { ... }
 
A locking policy, named ObserverLock, that indicates that synchronizing on the field observerLock (which must be declared to be final) protects the contents of the set observers.
 @Region("private ObserverRegion")
 @RegionLock("ObserverLock is observerLock protects ObserverRegion")
 class Observer {
   private final Object observerLock = new Object();
   ...
   @UniqueInRegion("ObserverRegion")
   private final Set<Callback> observers = new HashSet<Callback>();
   ...
   private void add(Callback c) {
     synchronized (observerLock) { observers.add(c); }
   }
   ...
 }
 
A locking policy, named StateLock, that indicates that locking on the java.util.concurrent.Lock stateLock protects the two long fields use to represent the position of the object.
 @Region("private AircraftState")
 @RegionLock("StateLock is stateLock protects AircraftState")
 public class Aircraft {
   private final Lock stateLock = new ReentrantLock();
   ...
   @InRegion("AircraftState")
   private long x, y;
   ...
   public void setPosition(long x, long y) {
     stateLock.lock();
     try {
       this.x = x;
       this.y = y;
     } finally {
       stateLock.unlock();
     }
   }
   ...
 }
 
The same lock object may be declared to be multiple locks (including to be a PolicyLock):
 @Regions({
   @Region("protected Color"),
   @Region("protected Position"),
   @Region("protected Label")
 })
 @RegionLocks({
   @RegionLock("L1 is this protects Color"),
   @RegionLock("L2 is this protects Position"),
   @RegionLock("L3 is lockField protects Label")
 })
 @PolicyLocks({
   @PolicyLock("P1 is this"),
   @PolicyLock("L1 is lockField")
 })
 public class Sprite {
   protected final Object lockField = new Object();
   ...
 }
 
Constructor annotation to support locking policies: To support the RegionLock annotation, a Unique or Borrowed annotation is needed on each constructor to assure that the object being constructed is confined to the thread that invoked new. A second less common approach, using effects, is described below.

Annotating @Unique("return") on a constructor is defined to be equivalent to annotating @Borrowed("this"). Either of these annotations indicate that the object being constructed is not aliased during construction, which implies that the reference "returned" by the new expression that invokes the constructor is unique. Which annotation is preferred, @Unique("return") or @Borrowed("this"), is a matter of programmer preference.

 @RegionLock("Lock is this protects Instance")
 public class Example {
 
   int x = 1;
   int y;
 
   @Unique("return")
   public Example(int y) {
     this.y = y;
   }
   ...
 }
 
Alternatively, you could use @Borrowed("this").
 @RegionLock("Lock is this protects Instance")
 public class Example {
 
   int x = 1;
   int y;
 
   @Borrowed("this")
   public Example(int y) {
     this.y = y;
   }
   ...
 }
 
It is also possible to support the RegionLock assertion with effects (Starts and RegionEffects) annotations on a constructor instead of using Unique or Borrowed. This is useful if the constructor aliases the receiver into a field within the newly constructed object. This situation is uncommon in real-world Java code. In the example below if an explicit lock object is not provided to the constructor then this is used and, hence, aliased into the field lock. In this code @Unique("return") cannot be verified so the effects annotations are used on the constructor instead.
 @Region("private Y")
 @RegionLock("Lock is lock protects Y")
 public class Example {
 
   private final Object lock;
   @InRegion("Y")
   private int y;
 
   @Starts("nothing")
   @RegionEffects("none")
   public Example(int y, Object lock) {
     this.y = y;
     if (lock == null)
       this.lock = this;
     else
       this.lock = lock;
   }
 
   public int getY() {
     synchronized (lock) {
       return y;
     }
   }
 
   public void setY(int value) {
     synchronized (lock) {
       y = value;
     }
   }
 }
 
The scoped promise Promise can be used if the constructor is implicit (i.e., generated by the compiler). It has the ability to place promises on implicit and explicit constructors.
 @RegionLock("Lock is this protects Instance")
 @Promise("@Unique(return) for new(**)")
 public class Example {
   int x = 1;
   int y = 1;
   ...
 }
 

Javadoc usage notes:

This annotation may placed in Javadoc, which can be useful for Java 1.4 code which does not include language support for annotations, via the @annotate tag.
 /**
  * @annotate RegionLock("SimpleLock is this protects Instance")
  */
 class Simple { ... }
 

See Also:
PolicyLock, RegionLocks, RequiresLock, ReturnsLock

Required Element Summary
 String value
          The value of this attribute must conform to the following grammar (in Augmented Backus–Naur Form):
 

Element Detail

value

public abstract String value
The value of this attribute must conform to the following grammar (in Augmented Backus–Naur Form):
 value = IDENTIFIER "is" lockExpression "protects" regionName
 
 lockExpression = simpleLockExpression / qualifiedLockExpression
 
 simpleLockExpression = 
   "class" /              ; the Class object referenced by the "class" pseudo-field of the annotated class
   "this" /               ; the instance itself
   ["this" "."] IDENTIFIER  ; the object referenced by the named field
 
 qualifiedLockExpression = 
   namedType "." "CLASS" /            ; the Class object referenced by the "class" pseudo-field of a named class
   namedType "." "THIS" /             ; a named enclosing instance
   namedType "." IDENTIFIER /         ; a named static field
   namedType "." THIS "." IDENTIFIER  ; a named field of an enclosing instance
 
 namedType = IDENTIFIER *("." IDENTIFIER)
 
 regionName = IDENTIFIER
 
 IDENTIFIER = Legal Java Identifier
 



Copyright © 2011 Surelogic, Inc.. All Rights Reserved.