[dom] Introduce AbortSignal::AlgorithmHandle and implement removal

This is the first CL aimed at making abort algorithm lifetime explicit.
Signals created by AbortSignal.any() need to remain alive as long as a
source signal can abort and the abort effect can be observed, which
includes abort algorithms having an effect. But we don't want source
signals to indefinitely keep dependent signals alive, so instead we
will tie the lifetime of dependent signals to the algorithms and enforce
algorithm lifetime management.

The full conversion is here: crrev.com/c/3712492. This is being split
because the conversion requires reasoning about algorithm lifetime for
each usage, and there are multiple directories/owners.

Changes in this CL:
 1. Introduce an AlgorithmHandle class and update AddAlgorithm() to
    return a handle
 2. Change AbortSignal to store a map of handles to algorithms, and
    implement removal as RemoveAlgorithm(handle)
 3. Introduce AbortSignalRegistry to help manage algorithm lifetime
    for event listeners. This class is used further in the any()
    implementation, but is used here to minimize the memory footprint
    of handles for event listeners (see the design doc).
 4. Add a helper class, ScopedAbortState, to help with cases where
    removal should be scoped to an operation, e.g. where removal
    can't wait for GC. Convert modules/eyedropper to use this.
 5. Convert a couple uses of AddAlgorithm() where lifetime management
    is straightforward
 6. Wrap all of this behind a feature/kill switch. This required
    factoring out the abort algorithm collection interface and
    making two subclasses.

Followup work for after all the callsites have been converted:
 1. Make AddAlgorithm() [[nodiscard]] to enforce callers use the
    handle
 2. Make the AbortSignal's algorithm map hold a weak pointer to
    handles, which we can't do this until all the callsites are
    converted
 3. When we implement AbortSignal.any(), we'll subclass
    AlgorithmHandle to store a strong reference to the signal for
    dependent signals, tying their lifetime to the algorithm

Testing:
 1. An internal wpt test is added to over the event listeners/registry
    change.
 2. Unit tests cover the expected removal behavior, but will need
    to be modified once the algorithm collection stores weak pointers.
 3. Callsites that depend on RemoveAlgorithm() will be flag-guarded and
    keep the old behavior. Both code paths are tested via a virtual
    test suite (eyedropper is added here as an example).

Design doc:
https://docs.google.com/document/d/1UMZrd5-RztLLUZ2g4vf4Nk7MBTnpfdihNi1Xh5qrND8/edit?usp=sharing&resourcekey=0-Xd_3IULrml81fZ7CGrltYw

Bug: 1296280, 1323391
LOW_COVERAGE_REASON = New code has coverage. event_target has coverage for new lines and eyedropper is missing some coverage for abort.

Change-Id: I8805d2ce01dab10c0319df46098d2aee485c2f8c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3931192
Reviewed-by: Nate Chapin <japhet@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Commit-Queue: Scott Haseley <shaseley@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1060639}
20 files changed
tree: 118c1de985dde981d3ba89776a81db4250abaef7
  1. android_webview/
  2. apps/
  3. ash/
  4. base/
  5. build/
  6. build_overrides/
  7. buildtools/
  8. cc/
  9. chrome/
  10. chromecast/
  11. chromeos/
  12. codelabs/
  13. components/
  14. content/
  15. courgette/
  16. crypto/
  17. dbus/
  18. device/
  19. docs/
  20. extensions/
  21. fuchsia_web/
  22. gin/
  23. google_apis/
  24. google_update/
  25. gpu/
  26. headless/
  27. infra/
  28. ios/
  29. ipc/
  30. media/
  31. mojo/
  32. native_client_sdk/
  33. net/
  34. pdf/
  35. ppapi/
  36. printing/
  37. remoting/
  38. rlz/
  39. sandbox/
  40. services/
  41. skia/
  42. sql/
  43. storage/
  44. styleguide/
  45. testing/
  46. third_party/
  47. tools/
  48. ui/
  49. url/
  50. weblayer/
  51. .clang-format
  52. .clang-tidy
  53. .eslintrc.js
  54. .git-blame-ignore-revs
  55. .gitattributes
  56. .gitignore
  57. .gn
  58. .mailmap
  59. .rustfmt.toml
  60. .vpython3
  61. .yapfignore
  62. AUTHORS
  63. BUILD.gn
  64. CODE_OF_CONDUCT.md
  65. codereview.settings
  66. DEPS
  67. DIR_METADATA
  68. ENG_REVIEW_OWNERS
  69. LICENSE
  70. LICENSE.chromium_os
  71. OWNERS
  72. PRESUBMIT.py
  73. PRESUBMIT_test.py
  74. PRESUBMIT_test_mocks.py
  75. README.md
  76. WATCHLISTS
README.md

Logo Chromium

Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all users to experience the web.

The project's web site is https://www.chromium.org.

To check out the source code locally, don't use git clone! Instead, follow the instructions on how to get the code.

Documentation in the source is rooted in docs/README.md.

Learn how to Get Around the Chromium Source Code Directory Structure .

For historical reasons, there are some small top level directories. Now the guidance is that new top level directories are for product (e.g. Chrome, Android WebView, Ash). Even if these products have multiple executables, the code should be in subdirectories of the product.

If you found a bug, please file it at https://crbug.com/new.