summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Suereth <Joshua.Suereth@gmail.com>2012-07-20 09:44:14 -0700
committerJosh Suereth <Joshua.Suereth@gmail.com>2012-07-20 09:44:14 -0700
commit46da0ee29f380ccb455c9c3c2adcf375e0c13ccf (patch)
tree7b160be5bcbfe37247841e732b7571fe5661f8c8
parentd1fd58fceeb607fab091d6c942c5619be57bf227 (diff)
parentddd5f3aa8f080328e98f656fd5f5d2946b5aa77f (diff)
downloadscala-46da0ee29f380ccb455c9c3c2adcf375e0c13ccf.tar.gz
scala-46da0ee29f380ccb455c9c3c2adcf375e0c13ccf.tar.bz2
scala-46da0ee29f380ccb455c9c3c2adcf375e0c13ccf.zip
Merge pull request #956 from phaller/topic/sip14-critical-fix-await
SIP-14 - Fix critical Java compatibility issue in scala.concurrent.Await
-rw-r--r--src/library/scala/concurrent/package.scala78
-rw-r--r--test/files/jvm/scala-concurrent-tck.scala11
2 files changed, 52 insertions, 37 deletions
diff --git a/src/library/scala/concurrent/package.scala b/src/library/scala/concurrent/package.scala
index a6488b602f..a2ef42fac8 100644
--- a/src/library/scala/concurrent/package.scala
+++ b/src/library/scala/concurrent/package.scala
@@ -18,41 +18,6 @@ package object concurrent {
type CancellationException = java.util.concurrent.CancellationException
type TimeoutException = java.util.concurrent.TimeoutException
- @implicitNotFound("Don't call `Awaitable` methods directly, use the `Await` object.")
- sealed trait CanAwait
- private implicit object AwaitPermission extends CanAwait
-
- /**
- * `Await` is what is used to ensure proper handling of blocking for `Awaitable` instances.
- */
- object Await {
- /**
- * Invokes ready() on the awaitable, properly wrapped by a call to `scala.concurrent.blocking`.
- * ready() blocks until the awaitable has completed or the timeout expires.
- *
- * Throws a TimeoutException if the timeout expires, as that is in the contract of `Awaitable.ready`.
- * @param awaitable the `Awaitable` on which `ready` is to be called
- * @param atMost the maximum timeout for which to wait
- * @return the result of `awaitable.ready` which is defined to be the awaitable itself.
- */
- @throws(classOf[TimeoutException])
- def ready[T](awaitable: Awaitable[T], atMost: Duration): awaitable.type =
- blocking(awaitable.ready(atMost))
-
- /**
- * Invokes result() on the awaitable, properly wrapped by a call to `scala.concurrent.blocking`.
- * result() blocks until the awaitable has completed or the timeout expires.
- *
- * Throws a TimeoutException if the timeout expires, or any exception thrown by `Awaitable.result`.
- * @param awaitable the `Awaitable` on which `result` is to be called
- * @param atMost the maximum timeout for which to wait
- * @return the result of `awaitable.result`
- */
- @throws(classOf[Exception])
- def result[T](awaitable: Awaitable[T], atMost: Duration): T =
- blocking(awaitable.result(atMost))
- }
-
/** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
*
* The result becomes available once the asynchronous computation is completed.
@@ -85,5 +50,46 @@ package object concurrent {
* - TimeoutException - in the case that the blockable object timed out
*/
@throws(classOf[Exception])
- def blocking[T](body: =>T): T = BlockContext.current.blockOn(body)
+ def blocking[T](body: =>T): T = BlockContext.current.blockOn(body)(scala.concurrent.AwaitPermission)
+}
+
+package concurrent {
+ @implicitNotFound("Don't call `Awaitable` methods directly, use the `Await` object.")
+ sealed trait CanAwait
+
+ /**
+ * Internal usage only, implementation detail.
+ */
+ private[concurrent] object AwaitPermission extends CanAwait
+
+ /**
+ * `Await` is what is used to ensure proper handling of blocking for `Awaitable` instances.
+ */
+ object Await {
+ /**
+ * Invokes ready() on the awaitable, properly wrapped by a call to `scala.concurrent.blocking`.
+ * ready() blocks until the awaitable has completed or the timeout expires.
+ *
+ * Throws a TimeoutException if the timeout expires, as that is in the contract of `Awaitable.ready`.
+ * @param awaitable the `Awaitable` on which `ready` is to be called
+ * @param atMost the maximum timeout for which to wait
+ * @return the result of `awaitable.ready` which is defined to be the awaitable itself.
+ */
+ @throws(classOf[TimeoutException])
+ def ready[T](awaitable: Awaitable[T], atMost: Duration): awaitable.type =
+ blocking(awaitable.ready(atMost)(AwaitPermission))
+
+ /**
+ * Invokes result() on the awaitable, properly wrapped by a call to `scala.concurrent.blocking`.
+ * result() blocks until the awaitable has completed or the timeout expires.
+ *
+ * Throws a TimeoutException if the timeout expires, or any exception thrown by `Awaitable.result`.
+ * @param awaitable the `Awaitable` on which `result` is to be called
+ * @param atMost the maximum timeout for which to wait
+ * @return the result of `awaitable.result`
+ */
+ @throws(classOf[Exception])
+ def result[T](awaitable: Awaitable[T], atMost: Duration): T =
+ blocking(awaitable.result(atMost)(AwaitPermission))
+ }
}
diff --git a/test/files/jvm/scala-concurrent-tck.scala b/test/files/jvm/scala-concurrent-tck.scala
index 1209b710b0..43d4c9dc71 100644
--- a/test/files/jvm/scala-concurrent-tck.scala
+++ b/test/files/jvm/scala-concurrent-tck.scala
@@ -700,9 +700,18 @@ trait Blocking extends TestBase {
}
}
+ def testFQCNForAwaitAPI(): Unit = once {
+ done =>
+
+ assert(classOf[CanAwait].getName == "scala.concurrent.CanAwait")
+ assert(Await.getClass.getName == "scala.concurrent.Await")
+
+ done()
+ }
+
testAwaitSuccess()
testAwaitFailure()
-
+ testFQCNForAwaitAPI()
}
trait BlockContexts extends TestBase {