// 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 #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 CreateWithType( const char* name, scoped_refptr joiner, base::MessageLoop::Type type); static scoped_refptr Create( const char* name, scoped_refptr 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 CreateWithLoopAndComInitTypes( const char* name, scoped_refptr 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 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 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 joiner_; DISALLOW_COPY_AND_ASSIGN(AutoThread); }; } // namespace remoting #endif // REMOTING_AUTO_THREAD_H_