JavaMemoryModel: A different slant with reference leakage

From: Sylvia Else (sylviae@optushome.com.au)
Date: Sun Jan 18 2004 - 05:14:50 EST


Hi,

The discussion of reference leaking prompted me to devise the following
example to provide a different slant on things. My intent is to focus on
the issues that a developer must address when attempting to write secure code.

The Util class here allows the user to supply a delegate. If the user does
not supply one, then one is created internally. The class is not required
to be thread safe as such, but must not leak the reference to any
internally created delegate.

Since thread safety is not required, muti-threaded access could lead to
data races, and indeed does in both solutions below.

So, first a naive solution:

class Util {
     private boolean delegateProvidedByUser = false;
     private Delegate theDelegate = null;

     public void setDelegate(Delegate d) {
         delegateProvidedByUser = true;
         theDelegate = d;
     }

     public Delegate getDelegate() {
         if(delegateProvidedByUser)
             return theDelegate;
         else
             return null;
     }

     public void doWork() {
         if(theDelegate == null) {
             delegateProvidedByUser = false;
             theDelegate = new DelegateImpl();
         }
         // Do stuff with theDelegate.
     }
}

If all methods are called from one thread, then this works as required, but
some reorderings could cause the internally generated delegate reference to
be leaked.

So now a correct (I hope) solution. Note that for the purpose of this
example, I am unconcerned about the safety of DelgateImpl itself.

class Util {
     private Delegate internalDelegate;
     private Delegate userDelegate;

     public void setDelegate(Delegate d) {
         userDelegate = d;
         internalDelegate = null;
     }

     public Delegate getDelegate() {
         return userDelegate;
     }

     public void doWork() {
         Delegate d = userDelegate;
         if(d == null) {
             if(internalDelegate == null) {
                 internalDelegate = new DelegateImpl();
             d = internalDelegate;
         }
         // Do stuff with d.
     }
}

The point of this is that the developer has to use some line of reasoning
to show that the second implementation is correct. That reasoning needs to
be straightforward, obvious, and clearly not applicable to the first
implementation.

I'll reserve further comment for later.

Sylvia.

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:56 EDT