disown method
Drops the cleanup registered for value by abandonable, join or
run.
Returns whether anything was dropped. The lookup is by identity, so pass
the very object the body was handed. What an equal one finds depends on
the value and the platform: identical answers by value for numbers of
one type and for bools, and on some platforms for strings and records,
so an equal value of that kind may drop a registration somebody else
made. A resource such a value stands for is registered with onDispose
or onDiscard instead. Registrations made by those two carry no value
and are invisible here — they are dropped by the function those members
return; an unknown value is not an error. With two registrations for one
value the top one goes, one per call.
Stands next to the hand-over: before it, when the hand-over is synchronous
and may throw after its own work (emit of solo, for example), and
inside the same uncancellable section, when it is asynchronous.
Implementation
@override
bool disown(Object value) {
if (_owner.isFinished) {
throw StateError('$_owner has already finished, cannot disown');
}
// Both stores, and the newest wins: the unwinding moves the
// registrations it puts off out of the stack, and a late value can be
// registered while they are aside, so neither list alone holds the
// order. One waiting for an outcome that has not happened yet is still
// a registration, and handing the value on must still take it back.
List<_Cleanup>? found;
var at = -1;
void look(List<_Cleanup> list) {
for (var i = list.length - 1; i >= 0; i--) {
if (identical(list[i].value, value) &&
(found == null || list[i].order > found![at].order)) {
found = list;
at = i;
}
}
}
look(_owner._cleanups);
look(_owner._skipped);
if (found case final list?) {
list.removeAt(at).release();
return true;
}
return false;
}