25
25
import java .util .concurrent .CountDownLatch ;
26
26
import java .util .concurrent .TimeUnit ;
27
27
import java .util .concurrent .atomic .AtomicBoolean ;
28
+ import java .util .concurrent .atomic .AtomicReference ;
28
29
29
30
import static org .testng .Assert .assertTrue ;
30
31
import static org .testng .Assert .fail ;
@@ -192,7 +193,7 @@ public void flop(Throwable thr, String msg) {
192
193
asyncErrors .add (thr );
193
194
}
194
195
}
195
-
196
+
196
197
/**
197
198
* To flop means to "fail asynchronously", either by onErroring or by failing some TCK check triggered asynchronously.
198
199
* This method does *NOT* fail the test - it's up to inspections of the error to fail the test if required.
@@ -886,34 +887,39 @@ public Promise(TestEnvironment env) {
886
887
}
887
888
888
889
private ArrayBlockingQueue <T > abq = new ArrayBlockingQueue <T >(1 );
889
- private volatile T _value = null ;
890
+ private AtomicReference < T > _value = new AtomicReference < T >() ;
890
891
891
892
public T value () {
892
- if (isCompleted ()) {
893
- return _value ;
893
+ final T value = _value .get ();
894
+ if (value != null ) {
895
+ return value ;
894
896
} else {
895
897
env .flop ("Cannot access promise value before completion" );
896
898
return null ;
897
899
}
898
900
}
899
901
900
902
public boolean isCompleted () {
901
- return _value != null ;
903
+ return _value . get () != null ;
902
904
}
903
905
904
906
/**
905
907
* Allows using expectCompletion to await for completion of the value and complete it _then_
906
908
*/
907
909
public void complete (T value ) {
908
- abq .add (value );
910
+ if (_value .compareAndSet (null , value )) {
911
+ // we add the value to the queue such to wake up any expectCompletion which was triggered before complete() was called
912
+ abq .add (value );
913
+ }
909
914
}
910
915
911
916
/**
912
- * Completes the promise right away, it is not possible to expectCompletion on a Promise completed this way
917
+ * Same as complete.
918
+ *
919
+ * Keeping this method for binary compatibility.
913
920
*/
914
921
public void completeImmediatly (T value ) {
915
- complete (value ); // complete!
916
- _value = value ; // immediatly!
922
+ complete (value );
917
923
}
918
924
919
925
public void expectCompletion (long timeoutMillis , String errorMsg ) throws InterruptedException {
@@ -922,8 +928,6 @@ public void expectCompletion(long timeoutMillis, String errorMsg) throws Interru
922
928
923
929
if (val == null ) {
924
930
env .flop (String .format ("%s within %d ms" , errorMsg , timeoutMillis ));
925
- } else {
926
- _value = val ;
927
931
}
928
932
}
929
933
}
0 commit comments