Skip to content

Commit

Permalink
Make Vector safe to share across threads without synchronization
Browse files Browse the repository at this point in the history
  • Loading branch information
retronym committed May 4, 2018
1 parent 9ae5ee0 commit 580e313
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/library/scala/collection/immutable/Vector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package immutable
import scala.collection.mutable.{Builder, ReusableBuilder}

import scala.annotation.unchecked.uncheckedVariance
import scala.runtime.ScalaRunTime

/** $factoryInfo
* @define Coll `Vector`
Expand Down Expand Up @@ -218,6 +219,7 @@ final class Vector[+A] private[immutable] (private[collection] val startIndex: I
s.dirty = dirty
s.gotoPosWritable(focus, idx, focus ^ idx) // if dirty commit changes; go to new pos and prepare for writing
s.display0(idx & 31) = elem.asInstanceOf[AnyRef]
ScalaRunTime.releaseFence()
s
}

Expand All @@ -236,7 +238,7 @@ final class Vector[+A] private[immutable] (private[collection] val startIndex: I
}

override def prepended[B >: A](value: B): Vector[B] = {
if (endIndex != startIndex) {
val result = if (endIndex != startIndex) {
val blockIndex = (startIndex - 1) & ~31
val lo = (startIndex - 1) & 31

Expand Down Expand Up @@ -311,10 +313,12 @@ final class Vector[+A] private[immutable] (private[collection] val startIndex: I
s.display0 = elems
s
}
ScalaRunTime.releaseFence()
result
}

override def appended[B >: A](value: B): Vector[B] = {
if (endIndex != startIndex) {
val result = if (endIndex != startIndex) {
val blockIndex = endIndex & ~31
val lo = endIndex & 31

Expand Down Expand Up @@ -373,6 +377,8 @@ final class Vector[+A] private[immutable] (private[collection] val startIndex: I
s.display0 = elems
s
}
ScalaRunTime.releaseFence()
result
}


Expand Down Expand Up @@ -536,6 +542,7 @@ final class Vector[+A] private[immutable] (private[collection] val startIndex: I
s.gotoPosWritable(focus, blockIndex, focus ^ blockIndex)
s.preClean(d)
s.cleanLeftEdge(cutIndex - shift)
ScalaRunTime.releaseFence()
s
}

Expand All @@ -551,6 +558,7 @@ final class Vector[+A] private[immutable] (private[collection] val startIndex: I
s.gotoPosWritable(focus, blockIndex, focus ^ blockIndex)
s.preClean(d)
s.cleanRightEdge(cutIndex - shift)
ScalaRunTime.releaseFence()
s
}

Expand Down Expand Up @@ -641,6 +649,7 @@ final class VectorBuilder[A]() extends ReusableBuilder[A, Vector[A]] with Vector
val s = new Vector[A](0, size, 0) // should focus front or back?
s.initFrom(this)
if (depth > 1) s.gotoPos(0, size - 1) // we're currently focused to size - 1, not size!
ScalaRunTime.releaseFence()
s
}

Expand Down

0 comments on commit 580e313

Please sign in to comment.