前言

image.png

image.png
image.png

image.png

源码分析

自己的是20210315的源码,跟老师的版本不一样。
在client单击连接对端的时候,最后是调用MaybeStartThread函数来创建线程的。如果传入自己的线程指针则直接返回,否则创建Thread对象。
image.png

  1. Conductor::ConnectToPeer
  2. ->
  3. Conductor::InitializePeerConnection
  4. ->
  5. webrtc::CreatePeerConnectionFactory
  6. ->
  7. CreateModularPeerConnectionFactory(
  8. ***
  9. auto pc_factory = PeerConnectionFactory::Create(std::move(dependencies));
  10. **
  11. ->
  12. rtc::scoped_refptr<PeerConnectionFactory> PeerConnectionFactory::Create(
  13. PeerConnectionFactoryDependencies dependencies) {
  14. auto context = ConnectionContext::Create(&dependencies);
  15. if (!context) {
  16. return nullptr;
  17. }
  18. return new rtc::RefCountedObject<PeerConnectionFactory>(context,
  19. &dependencies);
  20. }
  21. ->
  22. rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create(
  23. PeerConnectionFactoryDependencies* dependencies) {
  24. auto context = new rtc::RefCountedObject<ConnectionContext>(dependencies);
  25. if (!context->channel_manager_->Init()) {
  26. return nullptr;
  27. }
  28. return context;
  29. }
  30. ->
  31. ConnectionContext::ConnectionContext
  32. ->
  33. MaybeStartThread

MaybeStartThread

  1. rtc::Thread* MaybeStartThread(rtc::Thread* old_thread,
  2. const std::string& thread_name,
  3. bool with_socket_server,
  4. std::unique_ptr<rtc::Thread>& thread_holder) {
  5. if (old_thread) {
  6. return old_thread;
  7. }
  8. if (with_socket_server) {
  9. thread_holder = rtc::Thread::CreateWithSocketServer();
  10. } else {
  11. thread_holder = rtc::Thread::Create();
  12. }
  13. thread_holder->SetName(thread_name, nullptr);
  14. thread_holder->Start();
  15. return thread_holder.get();
  16. }

在里面的Thread::Start函数里面创建了线程,Windows则调用CreateThread,Linux调用pthread_create

Thread::Start

  1. bool Thread::Start() {
  2. RTC_DCHECK(!IsRunning());
  3. if (IsRunning())
  4. return false;
  5. Restart(); // reset IsQuitting() if the thread is being restarted
  6. // Make sure that ThreadManager is created on the main thread before
  7. // we start a new thread.
  8. ThreadManager::Instance();
  9. owned_ = true;
  10. #if defined(WEBRTC_WIN)
  11. thread_ = CreateThread(nullptr, 0, PreRun, this, 0, &thread_id_);
  12. if (!thread_) {
  13. return false;
  14. }
  15. #elif defined(WEBRTC_POSIX)
  16. pthread_attr_t attr;
  17. pthread_attr_init(&attr);
  18. int error_code = pthread_create(&thread_, &attr, PreRun, this);
  19. if (0 != error_code) {
  20. RTC_LOG(LS_ERROR) << "Unable to create pthread, error " << error_code;
  21. thread_ = 0;
  22. return false;
  23. }
  24. RTC_DCHECK(thread_);
  25. #endif
  26. return true;
  27. }

这里主要是说 CreateThread(nullptr, 0, PreRun, this, 0, &threadid);
线程创建完,则会调用PreRun

Thread::PreRun

  1. #if defined(WEBRTC_WIN)
  2. DWORD WINAPI Thread::PreRun(LPVOID pv) {
  3. #else
  4. void* Thread::PreRun(void* pv) {
  5. #endif
  6. Thread* thread = static_cast<Thread*>(pv);
  7. ThreadManager::Instance()->SetCurrentThread(thread);
  8. rtc::SetCurrentThreadName(thread->name_.c_str());
  9. #if defined(WEBRTC_MAC)
  10. ScopedAutoReleasePool pool;
  11. #endif
  12. thread->Run();
  13. ThreadManager::Instance()->SetCurrentThread(nullptr);
  14. #ifdef WEBRTC_WIN
  15. return 0;
  16. #else
  17. return nullptr;
  18. #endif
  19. } // namespace rtc

Thread::Run

  1. void Thread::Run() {
  2. ProcessMessages(kForever);
  3. }
  4. -》 主要是 Dispatch(&msg);
  5. bool Thread::ProcessMessages(int cmsLoop) {
  6. // Using ProcessMessages with a custom clock for testing and a time greater
  7. // than 0 doesn't work, since it's not guaranteed to advance the custom
  8. // clock's time, and may get stuck in an infinite loop.
  9. RTC_DCHECK(GetClockForTesting() == nullptr || cmsLoop == 0 ||
  10. cmsLoop == kForever);
  11. int64_t msEnd = (kForever == cmsLoop) ? 0 : TimeAfter(cmsLoop);
  12. int cmsNext = cmsLoop;
  13. while (true) {
  14. #if defined(WEBRTC_MAC)
  15. ScopedAutoReleasePool pool;
  16. #endif
  17. Message msg;
  18. if (!Get(&msg, cmsNext))
  19. return !IsQuitting();
  20. Dispatch(&msg);
  21. if (cmsLoop != kForever) {
  22. cmsNext = static_cast<int>(TimeUntil(msEnd));
  23. if (cmsNext < 0)
  24. return true;
  25. }
  26. }
  27. }
  28. -》 主要是 pmsg->phandler->OnMessage
  29. void Thread::Dispatch(Message* pmsg) {
  30. TRACE_EVENT2("webrtc", "Thread::Dispatch", "src_file",
  31. pmsg->posted_from.file_name(), "src_func",
  32. pmsg->posted_from.function_name());
  33. RTC_DCHECK_RUN_ON(this);
  34. int64_t start_time = TimeMillis();
  35. pmsg->phandler->OnMessage(pmsg);
  36. int64_t end_time = TimeMillis();
  37. int64_t diff = TimeDiff(end_time, start_time);
  38. if (diff >= dispatch_warning_ms_) {
  39. RTC_LOG(LS_INFO) << "Message to " << name() << " took " << diff
  40. << "ms to dispatch. Posted from: "
  41. << pmsg->posted_from.ToString();
  42. // To avoid log spew, move the warning limit to only give warning
  43. // for delays that are larger than the one observed.
  44. dispatch_warning_ms_ = diff + 1;
  45. }
  46. }

学习资料

WebRTC源码分析-线程基础之线程基本功能
https://www.jianshu.com/p/32fcf61c48e6
WebRTC源码分析-线程基础之消息循环,消息投递
https://www.jianshu.com/p/a3547ffefbeb