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