前言

image.png
image.png
messagequeue里面的Thread,对应thread_local_storage的一个Thread。
image.png

源码分析

image.png

  1. int PASCAL wWinMain(HINSTANCE instance,
  2. HINSTANCE prev_instance,
  3. wchar_t* cmd_line,
  4. int cmd_show) {
  5. rtc::WinsockInitializer winsock_init;
  6. rtc::Win32SocketServer w32_ss;
  7. // 创建完成时候,就已经添加到ThreadManager 了。
  8. rtc::Win32Thread w32_thread(&w32_ss);
  9. // 设置为当前线程与Win32Thread线程对象的绑定
  10. rtc::ThreadManager::Instance()->SetCurrentThread(&w32_thread);
  11. *******
  12. ->
  13. ThreadManager::SetCurrentThread(Thread* thread)
  14. ->
  15. void ThreadManager::SetCurrentThreadInternal(Thread* thread) {
  16. TlsSetValue(key_, thread);
  17. }

TlsSetValue函数里面的key参数值是 ThreadManager 的构造函数传入的, key(TlsAlloc()),调用TlsAlloc函数生成线程本地空间,然后调用了TlsSetValue存储thread线程指针地址到本地空间。

Win32Thread对象怎么插入到ThreadManager中?

通过查看Thread类的构造函数,可以发现构造时,最终都会调用Thread::Thread(SocketServer* ss, bool do_init)

Thread::Thread(SocketServer* ss, bool do_init)

  1. Thread::Thread(SocketServer* ss, bool do_init)
  2. : fPeekKeep_(false),
  3. delayed_next_num_(0),
  4. fInitialized_(false),
  5. fDestroyed_(false),
  6. stop_(0),
  7. ss_(ss) {
  8. RTC_DCHECK(ss);
  9. ss_->SetMessageQueue(this);
  10. SetName("Thread", this); // default name
  11. if (do_init) {
  12. DoInit();
  13. }
  14. }

里面最关键的是调用了Thread::DoInit,里面将Thread添加到了ThreadManager线程管理中了。

Thread::DoInit

  1. void Thread::DoInit() {
  2. if (fInitialized_) {
  3. return;
  4. }
  5. fInitialized_ = true;
  6. ThreadManager::Add(this);
  7. }

ThreadManager::Add(Thread* message_queue)

  1. void ThreadManager::Add(Thread* message_queue) {
  2. return Instance()->AddInternal(message_queue);
  3. }
  4. void ThreadManager::AddInternal(Thread* message_queue) {
  5. CritScope cs(&crit_);
  6. // Prevent changes while the list of message queues is processed.
  7. RTC_DCHECK_EQ(processing_, 0);
  8. message_queues_.push_back(message_queue);
  9. }

最终将messagequeue添加到message_queues容器中。