Skip to content

Commit 51d3fd2

Browse files
committed
Finish porting concurrency classes without separation checking
1 parent bc42db7 commit 51d3fd2

File tree

6 files changed

+24
-25
lines changed

6 files changed

+24
-25
lines changed

scala2-library-cc/src/scala/concurrent/BatchingExecutor.scala

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,7 @@ import language.experimental.captureChecking
2323
* Marker trait to indicate that a Runnable is Batchable by BatchingExecutors
2424
*/
2525
trait Batchable {
26-
self: Runnable =>
27-
}
28-
29-
trait Batchable2 {
30-
26+
self: Runnable^ =>
3127
}
3228

3329
private[concurrent] object BatchingExecutorStatics {

scala2-library-cc/src/scala/concurrent/ExecutionContext.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import java.util.concurrent.{ ExecutorService, Executor }
1616
import scala.annotation.implicitNotFound
1717

1818
import language.experimental.captureChecking
19+
import caps.Capability
1920

2021
/**
2122
* An `ExecutionContext` can execute program logic asynchronously,
@@ -70,7 +71,7 @@ consider using Scala's global ExecutionContext by defining
7071
the following:
7172
7273
implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global""")
73-
trait ExecutionContext {
74+
trait ExecutionContext extends Capability {
7475

7576
/** Runs a block of code on this execution context.
7677
*

scala2-library-cc/src/scala/concurrent/Future.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ trait Future[+T] extends Awaitable[T] {
296296
* @return a `Future` which will hold the successful result of this `Future` if it matches the predicate or a `NoSuchElementException`
297297
* @group Transformations
298298
*/
299-
def filter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T] =
299+
def filter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T]^{p, executor, this} =
300300
transform {
301301
t =>
302302
if (t.isInstanceOf[Success[T]]) {
@@ -308,7 +308,7 @@ trait Future[+T] extends Awaitable[T] {
308308
/** Used by for-comprehensions.
309309
* @group Transformations
310310
*/
311-
final def withFilter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T] = filter(p)(executor)
311+
final def withFilter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T]^{p, executor, this} = filter(p)(executor)
312312

313313
/** Creates a new future by mapping the value of the current future, if the given partial function is defined at that value.
314314
*

scala2-library-cc/src/scala/concurrent/Promise.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import language.experimental.captureChecking
3838
trait Promise[T] {
3939
/** Future containing the value of this promise.
4040
*/
41-
def future: Future[T]
41+
def future: Future[T]^
4242

4343
/** Returns whether the promise has already been completed with
4444
* a value or an exception.

scala2-library-cc/src/scala/concurrent/impl/ExecutionContextImpl.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private[concurrent] object ExecutionContextImpl {
8282
})
8383
}
8484

85-
def createDefaultExecutorService(reporter: Throwable => Unit): ExecutionContextExecutorService^{reporter} = {
85+
def createDefaultExecutorService(reporter: Throwable => Unit): ExecutionContextExecutorService^ = {
8686
def getInt(name: String, default: String) = (try System.getProperty(name, default) catch {
8787
case e: SecurityException => default
8888
}) match {
@@ -112,14 +112,14 @@ private[concurrent] object ExecutionContextImpl {
112112
}
113113
}
114114

115-
def fromExecutor(e: Executor, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextExecutor^{reporter} =
115+
def fromExecutor(e: Executor, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextExecutor^ =
116116
e match {
117117
case null => createDefaultExecutorService(reporter)
118118
case some => new ExecutionContextImpl(some, reporter)
119119
}
120120

121121
def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter):
122-
ExecutionContextExecutorService^{reporter} = es match {
122+
ExecutionContextExecutorService^ = es match {
123123
case null => createDefaultExecutorService(reporter)
124124
case some =>
125125
new ExecutionContextImpl(some, reporter) with ExecutionContextExecutorService {

scala2-library-cc/src/scala/concurrent/impl/Promise.scala

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
package scala.concurrent.impl
1414

15-
import scala.concurrent.{Batchable, Batchable2, CanAwait, ExecutionContext, ExecutionException, Future, TimeoutException}
15+
import scala.concurrent.{Batchable, CanAwait, ExecutionContext, ExecutionException, Future, TimeoutException}
1616
import scala.concurrent.duration.Duration
1717
import scala.annotation.{nowarn, switch, tailrec}
1818
import scala.util.control.{ControlThrowable, NonFatal}
@@ -24,6 +24,7 @@ import java.util.Objects.requireNonNull
2424
import java.io.{IOException, NotSerializableException, ObjectInputStream, ObjectOutputStream}
2525

2626
import language.experimental.captureChecking
27+
import caps.unsafe.*
2728

2829
/**
2930
* Latch used to implement waiting on a DefaultPromise's result.
@@ -61,19 +62,19 @@ private[concurrent] object Promise {
6162
* If when compressing a chain of Links it is discovered that the root has been completed,
6263
* the `owner`'s value is completed with that value, and the Link chain is discarded.
6364
**/
64-
private[concurrent] final class Link[T](to: DefaultPromise[T]) extends AtomicReference[DefaultPromise[T]](to) {
65+
private[concurrent] final class Link[T](to: DefaultPromise[T]^) extends AtomicReference[DefaultPromise[T]^{to}](to) {
6566
/**
6667
* Compresses this chain and returns the currently known root of this chain of Links.
6768
**/
68-
final def promise(owner: DefaultPromise[T]): DefaultPromise[T] = {
69+
final def promise(owner: DefaultPromise[T]^): DefaultPromise[T]^{this, to, owner} = {
6970
val c = get()
7071
compressed(current = c, target = c, owner = owner)
7172
}
7273

7374
/**
7475
* The combination of traversing and possibly unlinking of a given `target` DefaultPromise.
7576
**/
76-
@inline @tailrec private[this] final def compressed(current: DefaultPromise[T], target: DefaultPromise[T], owner: DefaultPromise[T]): DefaultPromise[T] = {
77+
@inline @tailrec private[this] final def compressed(current: DefaultPromise[T]^, target: DefaultPromise[T]^, owner: DefaultPromise[T]^): DefaultPromise[T]^{this, current, target, owner} = {
7778
val value = target.get()
7879
if (value.isInstanceOf[Callbacks[_]]) {
7980
if (compareAndSet(current, target)) target // Link
@@ -105,6 +106,7 @@ private[concurrent] object Promise {
105106

106107
// Left non-final to enable addition of extra fields by Java/Scala converters in scala-java8-compat.
107108
class DefaultPromise[T] private[this] (initial: AnyRef) extends AtomicReference[AnyRef](initial) with scala.concurrent.Promise[T] with scala.concurrent.Future[T] with (Try[T] => Unit) {
109+
self: DefaultPromise[T]^ =>
108110
/**
109111
* Constructs a new, completed, Promise.
110112
*/
@@ -125,7 +127,7 @@ private[concurrent] object Promise {
125127
/**
126128
* Returns the associated `Future` with this `Promise`
127129
*/
128-
override final def future: Future[T] = this
130+
override final def future: Future[T]^ = (this : Future[T]^)
129131

130132
override final def transform[S](f: Try[T] => Try[S])(implicit executor: ExecutionContext): Future[S] =
131133
dispatchOrAddCallbacks(get(), new Transformation[T, S](Xform_transform, f, executor))
@@ -186,7 +188,7 @@ private[concurrent] object Promise {
186188
else this.asInstanceOf[Future[S]]
187189
}
188190

189-
override final def filter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T] = {
191+
override final def filter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T]^{p, executor, this} = {
190192
val state = get()
191193
if (!state.isInstanceOf[Failure[_]]) dispatchOrAddCallbacks(state, new Transformation[T, T](Xform_filter, p, executor)) // Short-circuit if we get a Success
192194
else this
@@ -343,7 +345,7 @@ private[concurrent] object Promise {
343345

344346
/** Link this promise to the root of another promise.
345347
*/
346-
@tailrec private[concurrent] final def linkRootOf(target: DefaultPromise[T], link: Link[T]): Unit =
348+
@tailrec private[concurrent] final def linkRootOf(target: DefaultPromise[T]^, link: Link[T]^): Unit =
347349
if (this ne target) {
348350
val state = get()
349351
if (state.isInstanceOf[Try[_]]) {
@@ -412,13 +414,13 @@ private[concurrent] object Promise {
412414
* function's type parameters are erased, and the _xform tag will be used to reify them.
413415
**/
414416
final class Transformation[-F, T] private[this] (
415-
private[this] final var _fun: Any -> Any,
416-
private[this] final var _ec: ExecutionContext,
417+
private[this] final val _fun: Any => Any,
418+
private[this] final val _ec: ExecutionContext,
417419
private[this] final var _arg: Try[F],
418420
private[this] final val _xform: Int
419421
) extends DefaultPromise[T]() with Callbacks[F] with Runnable with Batchable {
420422
final def this(xform: Int, f: _ => _, ec: ExecutionContext) =
421-
this(f.asInstanceOf[Any -> Any], ec.prepare(): @nowarn("cat=deprecation"), null, xform)
423+
this(f.asInstanceOf[Any => Any], ec.prepare(): @nowarn("cat=deprecation"), null, xform)
422424

423425
final def benefitsFromBatching: Boolean = _xform != Xform_onComplete && _xform != Xform_foreach
424426

@@ -429,12 +431,12 @@ private[concurrent] object Promise {
429431
final def submitWithValue(resolved: Try[F]): this.type = {
430432
_arg = resolved
431433
val e = _ec
432-
try e.execute(this) /* Safe publication of _arg, _fun, _ec */
434+
try e.execute(this.unsafeAssumePure) /* Safe publication of _arg, _fun, _ec */
433435
catch {
434436
case t: Throwable =>
435437
// _fun = null // allow to GC
436438
_arg = null // see above
437-
_ec = null // see above again
439+
// _ec = null // see above again
438440
handleFailure(t, e)
439441
}
440442

@@ -460,7 +462,7 @@ private[concurrent] object Promise {
460462
val ec = _ec
461463
// _fun = null // allow to GC
462464
_arg = null // see above
463-
_ec = null // see above
465+
// _ec = null // see above
464466
try {
465467
val resolvedResult: Try[_] =
466468
(_xform: @switch) match {

0 commit comments

Comments
 (0)