Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Create PeerConnection Threading Challenges

101 views
Skip to first unread message

Aaron Clauson

unread,
Dec 18, 2024, 4:58:18 PM12/18/24
to discuss-webrtc
I'm updating a Windows console app that perviously worked with the m90 version of webrtc.lib. The challenge I'm facing is I keep htting the aborts triggered by the current thread checks. THe webrtc.lib I'm using is a debug version and I would like to get my app working in debug mode.

I've created the smallest example I can come up with in the hopes that someone might be able to point me in the right direction.

    webrtc::PeerConnectionFactoryDependencies pcfDeps;
    pcfDeps.event_log_factory = std::make_unique<webrtc::RtcEventLogFactory>(pcfDeps.task_queue_factory.get());
    auto peerConnectionFactory = webrtc::CreateModularPeerConnectionFactory(std::move(pcfDeps));

    webrtc::PeerConnectionInterface::RTCConfiguration config;
    auto observer = new rtc::RefCountedObject<PcObserver>();
    auto dependencies = webrtc::PeerConnectionDependencies(observer);

    auto pcOrErr = peerConnectionFactory->CreatePeerConnectionOrError(config, std::move(dependencies));

The CreatePeerConnectionOrError triggers this fatal error:

#
# Fatal error in: ..\..\p2p\base\port_allocator.cc, line 110
# last system error: 0
# Check failed: thread_checker_.IsCurrent()
#

I have tried various combinations of rtc::Threads for pcfDeps but I'm down to trial and error so I'm hoping there's some advice on a better approach?

Any help appreciated.
Aaron

Philipp Hancke

unread,
Dec 18, 2024, 6:40:48 PM12/18/24
to discuss...@googlegroups.com

--
This list falls under the WebRTC Code of Conduct - https://webrtc.org/support/code-of-conduct.
---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/discuss-webrtc/dc9d719b-92df-4141-b63b-e9f8c3b213e4n%40googlegroups.com.

Vitaly Ivanov

unread,
Dec 18, 2024, 10:00:59 PM12/18/24
to discuss...@googlegroups.com
It's definitely old, but there's nothing good about peerconnection_client unless it was fixed recently - I remember commenting out this assert on a regular basis right after libwebrtc checkout.

Anyway, the assert crash happens due to libwebrtc being single-thread by design with a task queue attached to this thread - definitely not the easiest thing to use. The way I usually make it work is Conductor-like (referring to peerconnection_client) class derived from rtc::Thread, webrtc::PeerConnectionObserver and webrtc::CreateSessionDescriptionObserver with a loop doing rtc::Thread::Current()->ProcessMessages() in rtc::Thread::Run() override - this where CreatePeerConnectionFactory and such should be called from

Aaron Clauson

unread,
Dec 19, 2024, 6:16:29 AM12/19/24
to discuss-webrtc
Thanks for the reply.

Yes, and also the peer_connection_test classes.

The thing that confuses me about the Conductor class is that while the signaling_thread gets set as a peer connection factory dependency it is not subsequently used by the demo application? Apart from that I did try all the obvious combinations of threads to create the peer conenction on but each one either gives the same port allocator error or ends up blocked (workter and network threads).

It seems like the peer connection should be created from either the main thread or the singalling thread but both cases fail on the port allocator error for me. Does the example below represent how the signalling thread is meant to be used for creating and using the peer connection? If there is an example somewhere I'd be happy to peruse it. Most of the ones I've come across are prior to the change in threading models.

    std::cout << "On main thread, thread ID " << std::this_thread::get_id() << std::endl;

    auto signallingThread = rtc::Thread::CreateWithSocketServer();
    signallingThread->Start();
    auto networkThread = rtc::Thread::CreateWithSocketServer();
    networkThread->Start();
    auto workerThread = rtc::Thread::Create();
    workerThread->Start();

    webrtc::PeerConnectionFactoryDependencies pcfDeps;
    pcfDeps.signaling_thread = signallingThread.get();
    pcfDeps.network_thread = networkThread.get();
    pcfDeps.worker_thread = workerThread.get();

    pcfDeps.event_log_factory = std::make_unique<webrtc::RtcEventLogFactory>(pcfDeps.task_queue_factory.get());
    auto peerConnectionFactory = webrtc::CreateModularPeerConnectionFactory(std::move(pcfDeps));

    signallingThread->PostTask([&peerConnectionFactory]() {
      std::cout << "Attempting to create peer connection on thread ID " << std::this_thread::get_id() << std::endl;

      webrtc::PeerConnectionInterface::RTCConfiguration config;
      auto observer = new rtc::RefCountedObject<PcObserver>();
      auto dependencies = webrtc::PeerConnectionDependencies(observer);
      auto pcOrErr = peerConnectionFactory->CreatePeerConnectionOrError(config, std::move(dependencies));

      if (!pcOrErr.ok()) {
        std::cerr << "Error creating peer connection: " << pcOrErr.error().message() << std::endl;
      }
      else {
        std::cout << "Peer connection created." << std::endl;
        auto peerConnection = std::move(pcOrErr.value());
      }
    });

Result:
On main thread, thread ID 40536
Attempting to create peer connection on thread ID 8832



#
# Fatal error in: ..\..\p2p\base\port_allocator.cc, line 110
# last system error: 0
# Check failed: thread_checker_.IsCurrent()
#

Vitaly Ivanov

unread,
Dec 19, 2024, 8:06:52 AM12/19/24
to discuss...@googlegroups.com

Aaron Clauson

unread,
Dec 19, 2024, 8:58:51 AM12/19/24
to discuss-webrtc
@Vitaly thanks for the article. The threading explanation is in line with what I'd surmised. It would also mean my original example should. The simple console app has a single main thread which gets automatically set as the signalling thread. The attempt to create the peer connection is then involed on that same main (and singalling) thread and should pass the libwebrtc thread checks.

Maybe that port allocation thread check error is a bug. I'll try commenting out the code, as you mentioend, and see if it works. I also suspect it should work fine on a non-debug build so I'll test that as well.

Thanks.

Aaron Clauson

unread,
Dec 20, 2024, 3:16:11 AM12/20/24
to discuss-webrtc
>  Maybe that port allocation thread check error is a bug. I'll try commenting out the code, as you mentioend, and see if it works.

This became whack-a-mole and I gave up after commenting out the 4th failing check.

>  I also suspect it should work fine on a non-debug build so I'll test that as well.

With a release build my original example works correctly.

The conclusion is there is still some trick I'm missing to initialise and/or use the threads correctly, or, alternatively the debug thread checks are broken, at least on Windows.
Reply all
Reply to author
Forward
0 new messages