auto_thread.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef REMOTING_BASE_AUTO_THREAD_H_
  5. #define REMOTING_BASE_AUTO_THREAD_H_
  6. #include <string>
  7. #include "base/callback_forward.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/message_loop/message_pump_type.h"
  10. #include "base/threading/platform_thread.h"
  11. #include "base/threading/thread_checker.h"
  12. #include "build/build_config.h"
  13. #include "remoting/base/auto_thread_task_runner.h"
  14. namespace remoting {
  15. // Thread implementation that runs a MessageLoop on a new thread, and manages
  16. // the lifetime of the MessageLoop and thread by tracking references to the
  17. // thread's TaskRunner. The caller passes the thread's TaskRunner to each
  18. // object that needs to run code on the thread, and when no references to the
  19. // TaskRunner remain, the thread will exit. When the caller destroys this
  20. // object they will be blocked until the thread exits.
  21. // All pending tasks queued on the thread's message loop will run to completion
  22. // before the thread is terminated.
  23. //
  24. // After the thread is stopped, the destruction sequence is:
  25. //
  26. // (1) Thread::CleanUp()
  27. // (2) MessageLoop::~MessageLoop
  28. // (3.b) CurrentThread::DestructionObserver::WillDestroyCurrentMessageLoop
  29. class AutoThread : base::PlatformThread::Delegate {
  30. public:
  31. // Create an AutoThread with the specified message-loop |type| and |name|.
  32. // The supplied AutoThreadTaskRunner will be used to join and delete the
  33. // new thread when no references to it remain.
  34. static scoped_refptr<AutoThreadTaskRunner> CreateWithType(
  35. const char* name,
  36. scoped_refptr<AutoThreadTaskRunner> joiner,
  37. base::MessagePumpType type);
  38. static scoped_refptr<AutoThreadTaskRunner> Create(
  39. const char* name,
  40. scoped_refptr<AutoThreadTaskRunner> joiner);
  41. #if BUILDFLAG(IS_WIN)
  42. // Create an AutoThread initialized for COM. |com_init_type| specifies the
  43. // type of COM apartment to initialize.
  44. enum ComInitType { COM_INIT_NONE, COM_INIT_STA, COM_INIT_MTA };
  45. static scoped_refptr<AutoThreadTaskRunner> CreateWithLoopAndComInitTypes(
  46. const char* name,
  47. scoped_refptr<AutoThreadTaskRunner> joiner,
  48. base::MessagePumpType pump_type,
  49. ComInitType com_init_type);
  50. #endif
  51. // Construct the AutoThread. |name| identifies the thread for debugging.
  52. explicit AutoThread(const char* name);
  53. AutoThread(const AutoThread&) = delete;
  54. AutoThread& operator=(const AutoThread&) = delete;
  55. // Waits for the thread to exit, and then destroys it.
  56. ~AutoThread() override;
  57. // Starts the thread, running the specified type of MessageLoop. Returns
  58. // an AutoThreadTaskRunner through which tasks may be posted to the thread
  59. // if successful, or NULL on failure.
  60. //
  61. // Note: This function can't be called on Windows with the loader lock held;
  62. // i.e. during a DllMain, global object construction or destruction, atexit()
  63. // callback.
  64. //
  65. // NOTE: You must not call this MessageLoop's Quit method directly. The
  66. // thread will exit when no references to the TaskRunner remain.
  67. scoped_refptr<AutoThreadTaskRunner> StartWithType(base::MessagePumpType type);
  68. #if BUILDFLAG(IS_WIN)
  69. // Configures the thread to initialize the specified COM apartment type.
  70. // SetComInitType() must be called before Start().
  71. void SetComInitType(ComInitType com_init_type);
  72. #endif
  73. private:
  74. AutoThread(const char* name, AutoThreadTaskRunner* joiner);
  75. void QuitThread(base::OnceClosure quit_when_idle_closure);
  76. void JoinAndDeleteThread();
  77. // base::PlatformThread::Delegate methods:
  78. void ThreadMain() override;
  79. // Used to pass data to ThreadMain.
  80. struct StartupData;
  81. raw_ptr<StartupData> startup_data_;
  82. #if BUILDFLAG(IS_WIN)
  83. // Specifies which kind of COM apartment to initialize, if any.
  84. ComInitType com_init_type_;
  85. #endif
  86. // The thread's handle.
  87. base::PlatformThreadHandle thread_;
  88. // The name of the thread. Used for debugging purposes.
  89. std::string name_;
  90. // Flag used to indicate whether MessageLoop was quit properly.
  91. // This allows us to detect premature exit via MessageLoop::QuitWhenIdle().
  92. bool was_quit_properly_;
  93. // AutoThreadTaskRunner to post a task to to join & delete this thread.
  94. scoped_refptr<AutoThreadTaskRunner> joiner_;
  95. // Verifies that QuitThread() is called on the same thread as ThreadMain().
  96. base::ThreadChecker thread_checker_;
  97. };
  98. } // namespace remoting
  99. #endif // REMOTING_BASE_AUTO_THREAD_H_