register method

Registers a callback object. If cancellation has already occurred, the callback will have been run by the time this method returns.

Implementation

CancellationTokenRegistration register(CancellationCallback callback,
    [Object? state]) {
  // If not canceled, register the handler; if canceled already, run the
  // callback synchronously.
  if (!isCancellationRequested) {
    if (_disposed) {
      // return CancellationTokenRegistration(id, node)
    }

    _registrations ??= Registrations(this);

    CallbackNode? node;
    var id = 0;
    if (_registrations?.freeNodeList != null) {
      node = _registrations?.freeNodeList;
      if (node != null) {
        assert(
          node.prev != null,
          'Nodes in the free list should all have a null Prev',
        );
        _registrations?.freeNodeList = node.next;

        node
          ..id = id = _registrations!._nextAvailableId++
          ..callback = callback
          ..callbackState = state
          ..next = _registrations?.callbacks;
        _registrations?.callbacks = node;
        if (node.next != null) {
          node.next?.prev = node;
        }
      }
    }

    node ??= CallbackNode(_registrations!)
      ..id = id = _registrations!._nextAvailableId++
      ..callback = callback
      ..callbackState = state
      ..next = _registrations?.callbacks;

    if (node.next != null) {
      node.next?.prev = node;
    }
    _registrations?.callbacks = node;

    assert(id != 0, 'IDs should never be the reserved value 0.');
    if (!isCancellationRequested || _registrations!.unregister(id, node)) {
      return CancellationTokenRegistration(id, node);
    }
  }

  callback.call(state);
  return CancellationTokenRegistration(0, null);
}