diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2010-09-02 13:15:21 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2010-09-02 13:15:21 +0000 |
commit | 93fe8b8d9252297652d85d7f51965daa657676aa (patch) | |
tree | 5884cbbfd1dfd5d2ad75471483d012b0eb794079 | |
parent | 21af53483f83d91e69fec7097ecbe9e1524ca30c (diff) | |
download | scala-93fe8b8d9252297652d85d7f51965daa657676aa.tar.gz scala-93fe8b8d9252297652d85d7f51965daa657676aa.tar.bz2 scala-93fe8b8d9252297652d85d7f51965daa657676aa.zip |
Merged revisions 22897 via svnmerge from
https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk
........
r22897 | dragos | 2010-09-01 18:01:59 +0200 (Wed, 01 Sep 2010) | 1 line
Closes #1220. Stream.tail is now thread safe. Review by odersky.
........
-rw-r--r-- | src/library/scala/collection/immutable/Stream.scala | 10 | ||||
-rw-r--r-- | test/files/run/concurrent-stream.check | 3 | ||||
-rw-r--r-- | test/files/run/concurrent-stream.scala | 36 |
3 files changed, 46 insertions, 3 deletions
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 7660a1e2c8..40f71aa845 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -557,10 +557,14 @@ object Stream extends SeqFactory[Stream] { final class Cons[+A](hd: A, tl: => Stream[A]) extends Stream[A] { override def isEmpty = false override def head = hd - private[this] var tlVal: Stream[A] = _ - def tailDefined = tlVal ne null + @volatile private[this] var tlVal: Stream[A] = _ + def tailDefined: Boolean = tlVal ne null override def tail: Stream[A] = { - if (!tailDefined) { tlVal = tl } + if (!tailDefined) + synchronized { + if (!tailDefined) tlVal = tl + } + tlVal } } diff --git a/test/files/run/concurrent-stream.check b/test/files/run/concurrent-stream.check new file mode 100644 index 0000000000..d4adf84490 --- /dev/null +++ b/test/files/run/concurrent-stream.check @@ -0,0 +1,3 @@ +Testing standard cons. +Evaluation 0: List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +Evaluation 1: List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) diff --git a/test/files/run/concurrent-stream.scala b/test/files/run/concurrent-stream.scala new file mode 100644 index 0000000000..42c695964e --- /dev/null +++ b/test/files/run/concurrent-stream.scala @@ -0,0 +1,36 @@ +// test concurrent calls to Stream.tail +object Test { + +def slowRange(from: Int, until: Int, cons: (Int, => Stream[Int]) => Stream[Int]): Stream[Int] = { + var current = from + def next: Stream[Int] = { + Thread.sleep(100) + if (current >= until) Stream.empty + else { + val stream = cons(current, next) + current += 1 + stream + } + } + next +} + +def testCons(cons: (Int, => Stream[Int]) => Stream[Int]): Unit = { + import scala.actors.Actor._ + + val stream = slowRange(0, 10, cons) + val main = self + actor { main ! stream.toList } + actor { main ! stream.toList } + val eval0 = receive { case list: List[Int] => list } + val eval1 = receive { case list: List[Int] => list } + println("Evaluation 0: " + eval0) + println("Evaluation 1: " + eval1) +} + + def main(args: Array[String]) { + println("Testing standard cons.") + testCons(Stream.cons.apply(_, _)) + } +} + |