@@ -19,8 +19,10 @@ import kotlin.coroutines.*
19
19
*
20
20
* If [linkedScope] is `null`, the [CoroutineExceptionHandler] returned from this function has special behavior when
21
21
* passed to [createTestCoroutineScope]: the newly-created scope is linked to this handler. If [linkedScope] is not
22
- * null, then the resulting [CoroutineExceptionHandler] will be linked to it, and passing it to [TestCoroutineScope]
23
- * will not lead to it re-linking.
22
+ * null, then the resulting [CoroutineExceptionHandler] will be linked to it.
23
+ *
24
+ * Passing an already-linked instance to [TestCoroutineScope] will lead to it making its own copy with the same
25
+ * [handler].
24
26
*/
25
27
public fun TestExceptionHandler (
26
28
linkedScope : TestCoroutineScope ? = null,
@@ -30,22 +32,32 @@ public fun TestExceptionHandler(
30
32
/* * The [CoroutineExceptionHandler] corresponding to the given [handler]. */
31
33
internal class TestExceptionHandlerContextElement (
32
34
private val handler : TestCoroutineScope .(CoroutineContext , Throwable ) -> Unit ,
33
- private var testCoroutineScope : TestCoroutineScope ?
35
+ private var testCoroutineScope : TestCoroutineScope ? ,
36
+ private var owner : Any? = null
34
37
): AbstractCoroutineContextElement(CoroutineExceptionHandler ), CoroutineExceptionHandler
35
38
{
36
39
private val lock = SynchronizedObject ()
37
40
41
+ /* *
42
+ * Claims ownership of this [TestExceptionHandler], or returns its copy, owned and not linked to anything.
43
+ */
44
+ fun claimOwnershipOrCopy (owner : Any ): TestExceptionHandlerContextElement = synchronized(lock) {
45
+ if (this .owner == null && testCoroutineScope == null ) {
46
+ this .owner = owner
47
+ this
48
+ } else {
49
+ TestExceptionHandlerContextElement (handler, null , owner)
50
+ }
51
+ }
52
+
38
53
/* *
39
54
* Links a [TestCoroutineScope] to this, unless there's already one linked.
40
55
*/
41
- fun tryRegisterTestCoroutineScope ( scope : TestCoroutineScope ): Boolean =
56
+ fun registerTestCoroutineScope ( owner : Any , scope : TestCoroutineScope ) =
42
57
synchronized(lock) {
43
- if (testCoroutineScope != null ) {
44
- false
45
- } else {
46
- testCoroutineScope = scope
47
- true
48
- }
58
+ check(this .owner == = owner && testCoroutineScope == null )
59
+ testCoroutineScope = scope
60
+ this .owner = null
49
61
}
50
62
51
63
override fun handleException (context : CoroutineContext , exception : Throwable ) {
0 commit comments