]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/lazy/Lazy.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scl.runtime / src / org / simantics / scl / runtime / lazy / Lazy.java
1 package org.simantics.scl.runtime.lazy;
2
3 import org.simantics.scl.runtime.function.Function;
4 import org.simantics.scl.runtime.function.FunctionImpl1;
5 import org.simantics.scl.runtime.tuple.Tuple0;
6
7 public class Lazy {
8     private static final Function CYCLIC_EVALUATION_TRAP = new FunctionImpl1() {
9         @Override
10         public Object apply(Object p0) {
11             throw new RuntimeException("Cyclic dependency on lazy value.");
12         }
13     };
14     
15     volatile Function thunk;
16     volatile Object value;
17     
18     public Lazy(Function thunk) {
19         this.thunk = thunk;
20     }
21
22     public Object force() {
23         if(thunk == null)
24             return value;
25         else {
26             synchronized(this) {
27                 Function curThunk = thunk;
28                 if(curThunk != null) {
29                     thunk = CYCLIC_EVALUATION_TRAP;
30                     value = curThunk.apply(Tuple0.INSTANCE);
31                     thunk = null;
32                 }
33             }
34             return value;
35         }
36     }
37 }