Skip to content

LayerTreeHost construction race condition fix #1517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: wpe-2.38
Choose a base branch
from

Conversation

tomasz-karczewski-red
Copy link

@tomasz-karczewski-red tomasz-karczewski-red commented Jun 12, 2025

This fixes race condition happening during LayerTreeHost construction The problem is seen with Process Swap On Cross-Site Navigation enabled.

The race condition happens during LayerTreeHost construction. The scenario is:

  • on THREAD_A (main thread) LayerTreeHost constructor starts; it first creates AcceleratedSurfaceLibWPE, then ThreadedCompositor

  • ThreadedCompositor constructor creates run loop (m_compositingRunLoop), executes & synchronously waits for initialization task on the run loop. This task calls m_client.nativeSurfaceHandleForCompositing() on THREAD_B (compositing thread) and this ends up calling AcceleratedSurfaceLibWPE::initialize() Note: at this point, LayerTreeHost constructor hasn't set LayerTreeHost::m_compositor value yet

  • still on THREAD_B, AcceleratedSurfaceLibWPE::initialize connects backend events (wpe_renderer_backend_egl_target_set_client). And sometimes we get first frame_complete event quickly (I've only seen that with PSON enabled). The handler for frame_complete is already registered, and it calls surface.m_client.frameComplete(). And LayerTreeHost::frameComplete() calls 'm_compositor->frameComplete()', but this requires THREAD_A to already have set m_compositor value in ThreadedCompositor constructor, and some memory barrier between threads A & B. So m_compositor can be null here, which causes SIGSEGV.

The proposed fix introduces additional 'LayerTreeHost::initialized' atomic bool which enables to prevent this case and adds memory barrier (via atomic_bool load/store) between threads.

ca3045d

Build-Tests Layout-Tests
✅ 🛠 wpe-238-amd64-build ✅ 🧪 wpe-238-amd64-layout
✅ 🛠 wpe-238-arm32-build ✅ 🧪 wpe-238-arm32-layout

This fixes race condition happening during LayerTreeHost construction
The problem is seen with Process Swap On Cross-Site Navigation enabled.

The race condition happens during LayerTreeHost construction. The scenario is:

- on THREAD_A (main thread) LayerTreeHost constructor starts; it first
  creates AcceleratedSurfaceLibWPE, then ThreadedCompositor

- ThreadedCompositor constructor creates run loop (m_compositingRunLoop),
  executes & synchronously waits for initialization task on the run loop.
  This task calls m_client.nativeSurfaceHandleForCompositing() on THREAD_B (compositing thread)
  and this ends up calling AcceleratedSurfaceLibWPE::initialize()
  Note: at this point, LayerTreeHost constructor hasn't set
  LayerTreeHost::m_compositor value yet

- still on THREAD_B, AcceleratedSurfaceLibWPE::initialize connects backend
  events (wpe_renderer_backend_egl_target_set_client). And sometimes we get
  first frame_complete event quickly (I've only seen that with PSON enabled).
  The handler for frame_complete is already registered, and it calls surface.m_client.frameComplete().
  And LayerTreeHost::frameComplete() calls 'm_compositor->frameComplete()', but this
  requires THREAD_A to already have set m_compositor value in ThreadedCompositor
  constructor, and some memory barrier between threads A & B.
  So m_compositor can be null here, which causes SIGSEGV.

The proposed fix introduces additional 'LayerTreeHost::initialized' atomic bool
which enables to prevent this case and adds memory barrier (via atomic_bool load/store)
between threads.
@tomasz-karczewski-red
Copy link
Author

associated RDK ticket: https://jira.rdkcentral.com/jira/browse/RDKDEV-1128

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

2 participants