@@ -184,7 +184,11 @@ public fun Job.unregisterOnCompletion(registration: Job.Registration): Job.Regis
184184public fun Job.cancelFutureOnCompletion (future : Future <* >): Job .Registration =
185185 onCompletion(CancelFutureOnCompletion (this , future))
186186
187- internal fun Job.removeOnCompletion (node : LockFreeLinkedListNode ): Job .Registration =
187+ /* *
188+ * Removes a given node on completion.
189+ * @suppress **This is unstable API and it is subject to change.**
190+ */
191+ public fun Job.removeOnCompletion (node : LockFreeLinkedListNode ): Job .Registration =
188192 onCompletion(RemoveOnCompletion (this , node))
189193
190194/* *
@@ -214,9 +218,10 @@ public object EmptyRegistration : Job.Registration {
214218 * This is an open class designed for extension by more specific classes that might augment the
215219 * state and mare store addition state information for completed jobs, like their result values.
216220 *
217- * Initial state of this job is either _active_ when `active = true` or _new_ when `active = false`.
221+ * @param active when `true` the job is created in _active_ state, when `false` in _new_ state. See [Job] for details.
222+ * @suppress **This is unstable API and it is subject to change.**
218223 */
219- internal open class JobSupport (active : Boolean ) : AbstractCoroutineContextElement(Job ), Job {
224+ public open class JobSupport (active : Boolean ) : AbstractCoroutineContextElement(Job ), Job {
220225 /*
221226 === Internal states ===
222227
@@ -279,7 +284,7 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
279284 * Initializes parent job.
280285 * It shall be invoked at most once after construction after all other initialization.
281286 */
282- fun initParentJob (parent : Job ? ) {
287+ public fun initParentJob (parent : Job ? ) {
283288 check(registration == null )
284289 if (parent == null ) {
285290 registration = EmptyRegistration
@@ -295,26 +300,26 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
295300 /* *
296301 * Returns current state of this job.
297302 */
298- fun getState (): Any? = state
303+ protected fun getState (): Any? = state
299304
300305 /* *
301306 * Tries to update current [state][getState] of this job.
302307 */
303- fun updateState (expect : Any , update : Any? ): Boolean {
308+ internal fun updateState (expect : Any , update : Any? ): Boolean {
304309 if (! tryUpdateState(expect, update)) return false
305310 completeUpdateState(expect, update)
306311 return true
307312 }
308313
309- fun tryUpdateState (expect : Any , update : Any? ): Boolean {
314+ internal fun tryUpdateState (expect : Any , update : Any? ): Boolean {
310315 require(expect is Incomplete && update !is Incomplete ) // only incomplete -> completed transition is allowed
311316 if (! STATE .compareAndSet(this , expect, update)) return false
312317 // Unregister from parent job
313318 registration?.unregister() // volatile read registration _after_ state was updated
314319 return true // continues in completeUpdateState
315320 }
316321
317- fun completeUpdateState (expect : Any , update : Any? ) {
322+ internal fun completeUpdateState (expect : Any , update : Any? ) {
318323 // Invoke completion handlers
319324 val cause = (update as ? CompletedExceptionally )?.exception
320325 var completionException: Throwable ? = null
@@ -335,7 +340,7 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
335340
336341 }
337342 // otherwise -- do nothing (it was Empty*)
338- else -> check(expect == = EmptyActive || expect == EmptyNew )
343+ else -> check(expect is Empty )
339344 }
340345 // Do other (overridable) processing after completion handlers
341346 completionException?.let { handleCompletionException(it) }
@@ -359,7 +364,7 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
359364 }
360365
361366 // return: 0 -> false (not new), 1 -> true (started), -1 -> retry
362- protected fun startInternal (state : Any? ): Int {
367+ internal fun startInternal (state : Any? ): Int {
363368 when {
364369 // EMPTY_NEW state -- no completion handlers, new
365370 state == = EmptyNew -> {
@@ -379,10 +384,12 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
379384 }
380385 }
381386
382- // override to provide the actual start action
387+ /* *
388+ * Override to provide the actual [start] action.
389+ */
383390 protected open fun onStart () {}
384391
385- override fun getCompletionException (): Throwable {
392+ final override fun getCompletionException (): Throwable {
386393 val state = getState()
387394 return when (state) {
388395 is Incomplete -> throw IllegalStateException (" Job has not completed yet" )
@@ -442,7 +449,7 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
442449 cont.unregisterOnCompletion(onCompletion(ResumeOnCompletion (this , cont)))
443450 }
444451
445- fun removeNode (node : JobNode ) {
452+ internal fun removeNode (node : JobNode ) {
446453 // remove logic depends on the state of the job
447454 while (true ) { // lock-free loop on job state
448455 val state = this .state
@@ -475,14 +482,14 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
475482 /* *
476483 * Override to process any exceptions that were encountered while invoking [onCompletion] handlers.
477484 */
478- open fun handleCompletionException (closeException : Throwable ) {
485+ protected open fun handleCompletionException (closeException : Throwable ) {
479486 throw closeException
480487 }
481488
482489 /* *
483490 * Override for post-completion actions that need to do something with the state.
484491 */
485- open fun afterCompletion (state : Any? ) {}
492+ protected open fun afterCompletion (state : Any? ) {}
486493
487494 private fun makeNode (handler : CompletionHandler ): JobNode =
488495 (handler as ? JobNode )?.also { require(it.job == = this ) }
@@ -494,20 +501,10 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
494501 /* *
495502 * Interface for incomplete [state][getState] of a job.
496503 */
497- internal interface Incomplete {
504+ public interface Incomplete {
498505 val isActive: Boolean
499506 }
500507
501- private object EmptyNew : Incomplete {
502- override val isActive: Boolean get() = false
503- override fun toString (): String = " Empty{New}"
504- }
505-
506- private object EmptyActive : Incomplete {
507- override val isActive: Boolean get() = true
508- override fun toString (): String = " Empty{Active}"
509- }
510-
511508 private class NodeList (
512509 @Volatile
513510 var active : Int
@@ -535,12 +532,18 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
535532
536533 /* *
537534 * Class for a [state][getState] of a job that had completed exceptionally, including cancellation.
535+ *
536+ * @param cause the exceptional completion cause. If `cause` is null, then a [CancellationException]
537+ * if created on first get from [exception] property.
538538 */
539- internal open class CompletedExceptionally (cause : Throwable ? ) {
539+ public open class CompletedExceptionally (cause : Throwable ? ) {
540540 @Volatile
541541 private var _exception : Throwable ? = cause // materialize CancellationException on first need
542542
543- val exception: Throwable get() =
543+ /* *
544+ * Returns completion exception.
545+ */
546+ public val exception: Throwable get() =
544547 _exception ? : // atomic read volatile var or else create new
545548 CancellationException (" Job was cancelled" ).also { _exception = it }
546549
@@ -550,7 +553,14 @@ internal open class JobSupport(active: Boolean) : AbstractCoroutineContextElemen
550553 /* *
551554 * A specific subclass of [CompletedExceptionally] for cancelled jobs.
552555 */
553- internal class Cancelled (cause : Throwable ? ) : CompletedExceptionally(cause)
556+ public class Cancelled (cause : Throwable ? ) : CompletedExceptionally(cause)
557+ }
558+
559+ private val EmptyNew = Empty (false )
560+ private val EmptyActive = Empty (true )
561+
562+ private class Empty (override val isActive : Boolean ) : JobSupport.Incomplete {
563+ override fun toString (): String = " Empty{${if (isActive) " Active" else " New" } }"
554564}
555565
556566internal abstract class JobNode (
0 commit comments