| // 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. |
| virtual ~AutoThread(); |
| |
| // 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: |
| virtual 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_ |