Hi Sébastien,

Most publication in LazyTransformer is handled via the synchronized seq() 
method. However, LazyTransformer is being replaced as part 
of http://dev.clojure.org/jira/browse/CLJ-1669 so probably moot.

Alex



On Monday, March 9, 2015 at 5:40:11 PM UTC-5, Sébastien Bocq wrote:
>
> Hello,
>
> I noticed that LazyTransformer [1] implements mutable state without any 
> volatile or final modifier to guard its fields (it might not be an isolated 
> case in the core library e.g. SeqIterator.java).
>
> Isn't such class subject to unsafe publication?
>
>
> For example, considering only this part of the implementation:
>
> public final class LazyTransformer extends ... {
>
>  IStepper stepper;
>  Object first = null;
>  LazyTransformer rest = null;
>
>  public LazyTransformer(IStepper stepper){
>    this.stepper = stepper; 
>  } 
>
>  public static LazyTransformer create(IFn xform, Object coll){
>    return new LazyTransformer(new Stepper(xform, RT.iter(coll)));
>  } 
>   ... 
>
>  public Object first(){
>    if(stepper != null)
>      seq();
>    if(rest == null)
>      return null;
>    return first; 
>  }
>
>  public ISeq next(){
>    if(stepper != null)
>      seq(); 
>    if(rest == null)
>      return null;
>    return rest.seq(); 
>   }
>   ..
> }
>
> If LazyTransformer/create is called in in one thread and then another 
> thread calls 'first' or 'next' on the new object then I would say there's a 
> chance the second thread sees stepper == null. A real use case could be one 
> thread calling (dedup) [2], which creates lazy sequence with (sequence 
> <http://crossclj.info/ns/org.clojure/clojure/1.7.0-alpha5/clojure.core.html#_sequence>
>  
> (dedupe 
> <http://crossclj.info/ns/org.clojure/clojure/1.7.0-alpha5/clojure.core.html#_dedupe>)
>  
> coll), and then another thread iterates through the sequence, which I 
> suppose relies on 'first' and 'next'.
>
> To me it looks like the exact same situation as the one discussed on the 
> Java concurrency-interest here:
>
> http://jsr166-concurrency.10961.n7.nabble.com/Safe-publishing-strategy-tt12126.html
>
> I can't believe I'm the first to be worried by this so maybe I overlooked 
> something. But if I'm not wrong or if there is any doubt, next to 
> refactoring the code to use immutable classes with only final fields (my 
> preferred approach), wouldn't it be safer to declare at least 'stepper' as 
> volatile to prevent any of risk of nasty concurrency issue?
>
> Thanks,
> Sébastien
>
> [1] 
> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LazyTransformer.java
> [2] http://crossclj.info/fun/clojure.core/dedupe.html
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to