cherry-pick-db71a0afc1d0.patch 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Raymond Toy <[email protected]>
  3. Date: Thu, 19 Mar 2020 21:54:36 +0000
  4. Subject: Clear context from orphan handlers when BaseAudioContext is going
  5. away
  6. When preparing to collect a BaseAudioContext, go through all the
  7. rendering_orphan_handlers_ and deletable_orphan_handlers_ and remove
  8. the context from the handler. This ensures that these handlers no
  9. longer have references to the context when the BaseAudioContext is
  10. destroyed because in some cases, these orphan handlers will get pulled
  11. and access the context, which is already gone.
  12. Clearing these in a prefinalizer ensures these orphan handlers don't
  13. try to touch the context.
  14. Manually verified that the repro case no longer reproduces.
  15. Bug: 1062247
  16. Change-Id: I50d083743903eb9544e09aa1ee912fc880331501
  17. Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2107806
  18. Reviewed-by: Kentaro Hara <[email protected]>
  19. Reviewed-by: Hongchan Choi <[email protected]>
  20. Commit-Queue: Raymond Toy <[email protected]>
  21. Cr-Commit-Position: refs/heads/master@{#751814}
  22. diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
  23. index c232899becfa2810a3dd86b5404050498aeca84f..0004f0c9470620f3201afe1d5fe535f17bc963f3 100644
  24. --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
  25. +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
  26. @@ -187,6 +187,12 @@ void BaseAudioContext::Uninitialize() {
  27. DCHECK_EQ(resume_resolvers_.size(), 0u);
  28. }
  29. +void BaseAudioContext::Dispose() {
  30. + // BaseAudioContext is going away, so remove the context from the orphan
  31. + // handlers.
  32. + GetDeferredTaskHandler().ClearContextFromOrphanHandlers();
  33. +}
  34. +
  35. void BaseAudioContext::ContextLifecycleStateChanged(
  36. mojom::FrameLifecycleState state) {
  37. // Don't need to do anything for an offline context.
  38. diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
  39. index 8351bd861e871e441b467c509d16f930e083f2a8..88244e5f24775c5bd59057ae9ffff2149d110e1f 100644
  40. --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.h
  41. +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
  42. @@ -95,6 +95,7 @@ class MODULES_EXPORT BaseAudioContext
  43. public ContextLifecycleStateObserver {
  44. USING_GARBAGE_COLLECTED_MIXIN(BaseAudioContext);
  45. DEFINE_WRAPPERTYPEINFO();
  46. + USING_PRE_FINALIZER(BaseAudioContext, Dispose);
  47. public:
  48. // The state of an audio context. On creation, the state is Suspended. The
  49. @@ -119,6 +120,8 @@ class MODULES_EXPORT BaseAudioContext
  50. return dest ? dest->GetAudioDestinationHandler().IsInitialized() : false;
  51. }
  52. + void Dispose();
  53. +
  54. // Document notification
  55. void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
  56. void ContextDestroyed(ExecutionContext*) override;
  57. diff --git a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
  58. index e8fe36a1060ae846692f90bee836304ec593fc46..b1b189567dca1b83277f02952719d384c638b32b 100644
  59. --- a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
  60. +++ b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
  61. @@ -293,10 +293,7 @@ void DeferredTaskHandler::HandleDeferredTasks() {
  62. }
  63. void DeferredTaskHandler::ContextWillBeDestroyed() {
  64. - for (auto& handler : rendering_orphan_handlers_)
  65. - handler->ClearContext();
  66. - for (auto& handler : deletable_orphan_handlers_)
  67. - handler->ClearContext();
  68. + ClearContextFromOrphanHandlers();
  69. ClearHandlersToBeDeleted();
  70. // Some handlers might live because of their cross thread tasks.
  71. }
  72. @@ -359,6 +356,19 @@ void DeferredTaskHandler::ClearHandlersToBeDeleted() {
  73. active_source_handlers_.clear();
  74. }
  75. +void DeferredTaskHandler::ClearContextFromOrphanHandlers() {
  76. + DCHECK(IsMainThread());
  77. +
  78. + // |rendering_orphan_handlers_| and |deletable_orphan_handlers_| can
  79. + // be modified on the audio thread.
  80. + GraphAutoLocker locker(*this);
  81. +
  82. + for (auto& handler : rendering_orphan_handlers_)
  83. + handler->ClearContext();
  84. + for (auto& handler : deletable_orphan_handlers_)
  85. + handler->ClearContext();
  86. +}
  87. +
  88. void DeferredTaskHandler::SetAudioThreadToCurrentThread() {
  89. DCHECK(!IsMainThread());
  90. audio_thread_.store(CurrentThread(), std::memory_order_relaxed);
  91. diff --git a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
  92. index 0ede5f5b5dabeeef9decc94c94d91ddc7351c722..2900b0f7cf3c47c8e92cc3ad4dda665eabdc479f 100644
  93. --- a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
  94. +++ b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
  95. @@ -109,6 +109,9 @@ class MODULES_EXPORT DeferredTaskHandler final
  96. void RequestToDeleteHandlersOnMainThread();
  97. void ClearHandlersToBeDeleted();
  98. + // Clear the context from the rendering and deletable orphan handlers.
  99. + void ClearContextFromOrphanHandlers();
  100. +
  101. bool AcceptsTailProcessing() const { return accepts_tail_processing_; }
  102. void StopAcceptingTailProcessing() { accepts_tail_processing_ = false; }