Open webrtc data channel from glib::closure

Hi,

I have a question related to the creation of data channels with webrtcbin. I have one channel called service, and depending on what I receive on it, I’d like to dynamically create additional channels.

A simplified example would be:

let channel = webrtcbin.lock().unwrap().emit_by_name::<WebRTCDataChannel>(
    "create-data-channel",
    &[
        &"service",
        &gst::Structure::builder("config")
            .field("ordered", true)
            .build(),
    ],
);

channel.connect_closure(
    "on-message-data",
    false,
    glib::closure!(move |_channel: &WebRTCDataChannel, msg: &glib::Bytes| {
        // Some processing of msg

        let channel2 = webrtcbin.lock().unwrap().emit_by_name::<WebRTCDataChannel>(
            "create-data-channel",
            &[
                &"dynamic_name",
                &gst::Structure::builder("config")
                    .field("ordered", true)
                    .build(),
            ],
        );
        info!("never called");
    }),
);

However, channel2 is never created (dynamic_name would change depending on what I receive in service). The thread seems to be blocked here. Can I create a channel from within a closure like this?

Creating the two channels like this works, but I miss the information to properly name channel2:

let channel = webrtcbin.lock().unwrap().emit_by_name::<WebRTCDataChannel>(
    "create-data-channel",
    &[
        &"service",
        &gst::Structure::builder("config")
            .field("ordered", true)
            .build(),
    ],
);

let channel2 = webrtcbin.lock().unwrap().emit_by_name::<WebRTCDataChannel>(
    "create-data-channel",
    &[
        &"dynamic_name",
        &gst::Structure::builder("config")
            .field("ordered", true)
            .build(),
    ],
);

Thanks for your help!

It will probably work if you create the second data channel from a helper thread.

I assume webrtcbin holds a mutex while emitting the signal, and that same mutex is also used for creating data channels. That’s not ideal and should ideally be fixed. Can you create an issue about that in gitlab?

Thanks for the quick answer.

Spawning a thread works indeed.

let channel = webrtcbin.lock().unwrap().emit_by_name::<WebRTCDataChannel>(
    "create-data-channel",
    &[
        &"service",
        &gst::Structure::builder("config")
            .field("ordered", true)
            .build(),
    ],
);

let (tx, rx) = std::sync::mpsc::channel();
thread::spawn(move || {
    let id = rx.recv().unwrap();

    let channel2 = webrtcbin.lock().unwrap().emit_by_name::<WebRTCDataChannel>(
        "create-data-channel",
        &[
            &format!("dynamic_name_{}", id),
            &gst::Structure::builder("config")
                .field("ordered", true)
                .build(),
        ],
    );

    debug!("exit create channel2");
});

channel.connect_closure(
    "on-message-data",
    false,
    glib::closure!(move |_channel: &WebRTCDataChannel, msg: &glib::Bytes| {
        // Some processing to get id from msg
        let _ = tx.send(id);
    }),
);

Here’s the issue: emit_by_name::<WebRTCDataChannel> hangs from whithin a channel.connect_closure("on-message-data", ..) (#535) · Issues · GStreamer / gstreamer-rs · GitLab