|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef REMOTING_BASE_AUTO_THREAD_H_ | 
|  | #define REMOTING_BASE_AUTO_THREAD_H_ | 
|  |  | 
|  | #include <string> | 
|  |  | 
|  | #include "base/message_loop/message_loop.h" | 
|  | #include "base/threading/platform_thread.h" | 
|  | #include "remoting/base/auto_thread_task_runner.h" | 
|  |  | 
|  | namespace remoting { | 
|  |  | 
|  | // Thread implementation that runs a MessageLoop on a new thread, and manages | 
|  | // the lifetime of the MessageLoop and thread by tracking references to the | 
|  | // thread's TaskRunner.  The caller passes the thread's TaskRunner to each | 
|  | // object that needs to run code on the thread, and when no references to the | 
|  | // TaskRunner remain, the thread will exit.  When the caller destroys this | 
|  | // object they will be blocked until the thread exits. | 
|  | // All pending tasks queued on the thread's message loop will run to completion | 
|  | // before the thread is terminated. | 
|  | // | 
|  | // After the thread is stopped, the destruction sequence is: | 
|  | // | 
|  | //  (1) Thread::CleanUp() | 
|  | //  (2) MessageLoop::~MessageLoop | 
|  | //  (3.b)    MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop | 
|  | class AutoThread : base::PlatformThread::Delegate { | 
|  | public: | 
|  | // Create an AutoThread with the specified message-loop |type| and |name|. | 
|  | // The supplied AutoThreadTaskRunner will be used to join and delete the | 
|  | // new thread when no references to it remain. | 
|  | static scoped_refptr<AutoThreadTaskRunner> CreateWithType( | 
|  | const char* name, | 
|  | scoped_refptr<AutoThreadTaskRunner> joiner, | 
|  | base::MessageLoop::Type type); | 
|  | static scoped_refptr<AutoThreadTaskRunner> Create( | 
|  | const char* name, | 
|  | scoped_refptr<AutoThreadTaskRunner> joiner); | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | // Create an AutoThread initialized for COM.  |com_init_type| specifies the | 
|  | // type of COM apartment to initialize. | 
|  | enum ComInitType { COM_INIT_NONE, COM_INIT_STA, COM_INIT_MTA }; | 
|  | static scoped_refptr<AutoThreadTaskRunner> CreateWithLoopAndComInitTypes( | 
|  | const char* name, | 
|  | scoped_refptr<AutoThreadTaskRunner> joiner, | 
|  | base::MessageLoop::Type loop_type, | 
|  | ComInitType com_init_type); | 
|  | #endif | 
|  |  | 
|  | // Construct the AutoThread.  |name| identifies the thread for debugging. | 
|  | explicit AutoThread(const char* name); | 
|  |  | 
|  | // Waits for the thread to exit, and then destroys it. | 
|  | ~AutoThread() override; | 
|  |  | 
|  | // Starts the thread, running the specified type of MessageLoop.  Returns | 
|  | // an AutoThreadTaskRunner through which tasks may be posted to the thread | 
|  | // if successful, or NULL on failure. | 
|  | // | 
|  | // Note: This function can't be called on Windows with the loader lock held; | 
|  | // i.e. during a DllMain, global object construction or destruction, atexit() | 
|  | // callback. | 
|  | // | 
|  | // NOTE: You must not call this MessageLoop's Quit method directly.  The | 
|  | // thread will exit when no references to the TaskRunner remain. | 
|  | scoped_refptr<AutoThreadTaskRunner> StartWithType( | 
|  | base::MessageLoop::Type type); | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | // Configures the thread to initialize the specified COM apartment type. | 
|  | // SetComInitType() must be called before Start(). | 
|  | void SetComInitType(ComInitType com_init_type); | 
|  | #endif | 
|  |  | 
|  | private: | 
|  | AutoThread(const char* name, AutoThreadTaskRunner* joiner); | 
|  |  | 
|  | void QuitThread(scoped_refptr<base::SingleThreadTaskRunner> task_runner); | 
|  | void JoinAndDeleteThread(); | 
|  |  | 
|  | // base::PlatformThread::Delegate methods: | 
|  | void ThreadMain() override; | 
|  |  | 
|  | // Used to pass data to ThreadMain. | 
|  | struct StartupData; | 
|  | StartupData* startup_data_; | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | // Specifies which kind of COM apartment to initialize, if any. | 
|  | ComInitType com_init_type_; | 
|  | #endif | 
|  |  | 
|  | // The thread's handle. | 
|  | base::PlatformThreadHandle thread_; | 
|  |  | 
|  | // The name of the thread.  Used for debugging purposes. | 
|  | std::string name_; | 
|  |  | 
|  | // Flag used to indicate whether MessageLoop was quit properly. | 
|  | // This allows us to detect premature exit via MessageLoop::Quit(). | 
|  | bool was_quit_properly_; | 
|  |  | 
|  | // AutoThreadTaskRunner to post a task to to join & delete this thread. | 
|  | scoped_refptr<AutoThreadTaskRunner> joiner_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(AutoThread); | 
|  | }; | 
|  |  | 
|  | }  // namespace remoting | 
|  |  | 
|  | #endif  // REMOTING_AUTO_THREAD_H_ |