Fixed initialization of Job with parent (initParentJob), fixed handling on uncaught exceptions in standalone coroutines
diff --git a/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CancellableContinuation.kt b/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CancellableContinuation.kt
index 9723585..2895b4c 100644
--- a/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CancellableContinuation.kt
+++ b/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CancellableContinuation.kt
@@ -17,11 +17,11 @@
 
 /**
  * Suspend coroutine similar to [suspendCoroutine], but provide an implementation of [CancellableContinuation] to
- * the [block].
+ * the [block]. This function throws [CancellationException] if the coroutine is cancelled while suspended.
  */
 public inline suspend fun <T> suspendCancellableCoroutine(crossinline block: (CancellableContinuation<T>) -> Unit): T =
-    suspendCoroutineOrReturn { c ->
-        val safe = SafeCancellableContinuation(c)
+    suspendCoroutineOrReturn { cont ->
+        val safe = SafeCancellableContinuation(cont, getParentJobOrAbort(cont))
         block(safe)
         safe.getResult()
     }
@@ -29,12 +29,23 @@
 // --------------- implementation details ---------------
 
 @PublishedApi
+internal fun getParentJobOrAbort(cont: Continuation<*>): Job? {
+    val job = cont.context[Job]
+    // fast path when parent job is already complete (we don't even construct SafeCancellableContinuation object)
+    job?.isActive?.let { if (!it) throw CancellationException() }
+    return job
+}
+
+@PublishedApi
 internal class SafeCancellableContinuation<in T>(
-    private val delegate: Continuation<T>
+        private val delegate: Continuation<T>,
+        parentJob: Job?
 ) : AbstractCoroutine<T>(delegate.context), CancellableContinuation<T> {
     // only updated from the thread that invoked suspendCancellableCoroutine
     private var suspendedThread: Thread? = Thread.currentThread()
 
+    init { initParentJob(parentJob) }
+
     fun getResult(): Any? {
         if (suspendedThread != null) {
             suspendedThread = null