8000 Move Future.onCompleteWithUnregister out of the Future API · scala/scala3@e15e9c3 · GitHub
[go: up one dir, main page]

Skip to content

Commit e15e9c3

Browse files
committed
Move Future.onCompleteWithUnregister out of the Future API
This restores compatibility with existing `Future` subclasses. While we're not convinced this method should belong to the Future API, let's keep it internal.
1 parent d699135 commit e15e9c3

File tree

2 files changed

+16
-17
lines changed

2 files changed

+16
-17
lines changed

library/src/scala/concurrent/Future.scala

Lines change 8000 d: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@ package scala.concurrent
1414

1515
import java.util.concurrent.atomic.AtomicReference
1616
import java.util.concurrent.locks.LockSupport
17-
18-
import scala.util.control.{NonFatal, NoStackTrace}
17+
import scala.util.control.{NoStackTrace, NonFatal}
1918
import scala.util.{Failure, Success, Try}
2019
import scala.concurrent.duration._
2120
import scala.collection.BuildFrom
22-
import scala.collection.mutable.{Builder, ArrayBuffer}
21+
import scala.collection.mutable.{ArrayBuffer, Builder}
2322
import scala.reflect.ClassTag
24-
2523
import scala.concurrent.ExecutionContext.parasitic
24+
import scala.concurrent.impl.Promise.DefaultPromise
2625

2726
/** A `Future` represents a value which may or may not be currently available,
2827
* but will be available at some point, or an exception if that value could not be made available.
@@ -126,12 +125,6 @@ trait Future[+T] extends Awaitable[T] {
126125
*/
127126
def onComplete[U](f: Try[T] => U)(implicit executor: ExecutionContext): Unit
128127

129-
/** The same as [[onComplete]], but additionally returns a function which can be
130-
* invoked to unregister the callback function. Removing a callback from a long-lived
131-
* future can enable garbage collection of objects referenced by the closure.
132-
*/
133-
private[concurrent] def onCompleteWithUnregister[U](f: Try[T] => U)(implicit executor: ExecutionContext): () => Unit
134-
135128
/* Miscellaneous */
136129

137130
/** Returns whether the future had already been completed with
@@ -621,7 +614,6 @@ object Future {
621614
}
622615

623616
override final def onComplete[U](f: Try[Nothing] => U)(implicit executor: ExecutionContext): Unit = ()
624-
override private[concurrent] final def onCompleteWithUnregister[U](f: Try[Nothing] => U)(implicit executor: ExecutionContext): () => Unit = () => ()
625617
override final def isCompleted: Boolean = false
626618
override final def value: Option[Try[Nothing]] = None
627619
override final def failed: Future[Throwable] = this
@@ -751,10 +743,13 @@ object Future {
751743
while (i.hasNext && !completed) {
752744
val deregs = firstCompleteHandler.get
753745
if (deregs == null) completed = true
754-
else {
755-
val d = i.next().onCompleteWithUnregister(firstCompleteHandler)
756-
if (!firstCompleteHandler.compareAndSet(deregs, d :: deregs))
757-
d.apply()
746+
else i.next() match {
747+
case dp: DefaultPromise[T @unchecked] =>
748+
val d = dp.onCompleteWithUnregister(firstCompleteHandler)
749+
if (!firstCompleteHandler.compareAndSet(deregs, d :: deregs))
750+
d.apply()
751+
case f =>
752+
f.onComplete(firstCompleteHandler)
758753
}
759754
}
760755
p.future

library/src/scala/concurrent/impl/Promise.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,11 @@ private[concurrent] object Promise {
215215
override final def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit =
216216
dispatchOrAddCallbacks(get(), new Transformation[T, Unit](Xform_onComplete, func, executor))
217217

218-
override private[concurrent] final def onCompleteWithUnregister[U](func: Try[T] => U)(implicit executor: ExecutionContext): () => Unit = {
218+
/** The same as [[onComplete]], but additionally returns a function which can be
219+
* invoked to unregister the callback function. Removing a callback from a long-lived
220+
* future can enable garbage collection of objects referenced by the closure.
221+
*/
222+
private[concurrent] final def onCompleteWithUnregister[U](func: Try[T] => U)(implicit executor: ExecutionContext): () => Unit = {
219223
val t = new Transformation[T, Unit](Xform_onComplete, func, executor)
220224
dispatchOrAddCallbacks(get(), t)
221225
() => unregisterCallback(t)
@@ -518,7 +522,7 @@ private[concurrent] object Promise {
518522
if (v.isInstanceOf[Failure[F]]) {
519523
val f = fun.asInstanceOf[PartialFunction[Throwable, Future[T]]].applyOrElse(v.asInstanceOf[Failure[F]].exception, Future.recoverWithFailed)
520524
if (f ne Future.recoverWithFailedMarker) {
521-
if (f.isInstanceOf[DefaultPromise[T]]) f.asInstanceOf[DefaultPromise[T]].linkRootOf(this, null) else completeWith(f.asInstanceOf[Future[T]])
525+
if (f.isInstanceOf[DefaultPromise[_]]) f.asInstanceOf[DefaultPromise[T]].linkRootOf(this, null) else completeWith(f.asInstanceOf[Future[T]])
522526
null
523527
} else v
524528
} else v

0 commit comments

Comments
 (0)
0