auto_thread.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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.h"
11#include "base/threading/platform_thread.h"
12#include "remoting/base/auto_thread_task_runner.h"
13
14namespace 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
30class 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      MessageLoop::Type type);
39  static scoped_refptr<AutoThreadTaskRunner> Create(
40      const char* name,
41      scoped_refptr<AutoThreadTaskRunner> joiner);
42
43  // Construct the AutoThread.  |name| identifies the thread for debugging.
44  explicit AutoThread(const char* name);
45
46  // Waits for the thread to exit, and then destroys it.
47  virtual ~AutoThread();
48
49  // Starts a the thread, running the specified type of MessageLoop.  Returns
50  // an AutoThreadTaskRunner through which tasks may be posted to the thread
51  // if successful, or NULL on failure.
52  //
53  // Note: This function can't be called on Windows with the loader lock held;
54  // i.e. during a DllMain, global object construction or destruction, atexit()
55  // callback.
56  //
57  // NOTE: You must not call this MessageLoop's Quit method directly.  The
58  // thread will exit when no references to the TaskRunner remain.
59  scoped_refptr<AutoThreadTaskRunner> StartWithType(MessageLoop::Type type);
60
61  // Shorthand for StartWithType(MessageLoop::TYPE_DEFAULT).
62  scoped_refptr<AutoThreadTaskRunner> Start();
63
64 private:
65  AutoThread(const char* name, AutoThreadTaskRunner* joiner);
66
67  void QuitThread(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
68  void JoinAndDeleteThread();
69
70  // base::PlatformThread::Delegate methods:
71  virtual void ThreadMain() OVERRIDE;
72
73  // Used to pass data to ThreadMain.
74  struct StartupData;
75  StartupData* startup_data_;
76
77  // The thread's handle.
78  base::PlatformThreadHandle thread_;
79
80  // The name of the thread.  Used for debugging purposes.
81  std::string name_;
82
83  // Flag used to indicate whether MessageLoop was quit properly.
84  // This allows us to detect premature exit via MessageLoop::Quit().
85  bool was_quit_properly_;
86
87  // AutoThreadTaskRunner to post a task to to join & delete this thread.
88  scoped_refptr<AutoThreadTaskRunner> joiner_;
89
90  DISALLOW_COPY_AND_ASSIGN(AutoThread);
91};
92
93}  // namespace remoting
94
95#endif  // REMOTING_AUTO_THREAD_H_
96