Skip to content

webrtc-websys: RTCDataChannel callbacks can panic after stream teardown #6551

Description

@yexiyue

Summary

In browsers, libp2p-webrtc-websys can panic from an RTCDataChannel event callback after its Rust stream has been torn down:

Uncaught Error: closure invoked recursively or after being dropped
... at RTCDataChannel.<callback>

Root cause

PollDataChannel registers Rust wasm-bindgen closures as persistent RTCDataChannel event handlers. A browser may dispatch an event that was queued before the final Rust stream clone is dropped. If the corresponding Closure has already been released, the stale JavaScript handler invokes a dropped closure.

Calling AtomicWaker::wake() synchronously from the Web API callback can also re-enter polling while wasm-bindgen still holds a mutable borrow of that callback closure.

Proposed fix

  • Keep the DataChannel and all registered event callbacks in a shared owner for the lifetime of the final stream clone.
  • Detach each browser event handler before that owner releases its closures.
  • Defer waker notifications until the Web API callback has returned.

Validation

A focused implementation is available in #6558. It passes the wasm32 build check and removes the browser callback exception in browser-to-browser WebRTC relay transfer testing; the same transfer completes successfully.

The relay frame-size failure found during this investigation is independent and tracked separately in #6557.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions