Chromium Code Reviews| Index: remoting/base/auto_thread_task_runner.h |
| diff --git a/remoting/base/auto_thread_task_runner.h b/remoting/base/auto_thread_task_runner.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..793142f7b387576955ec210ff9f1be94e03ade07 |
| --- /dev/null |
| +++ b/remoting/base/auto_thread_task_runner.h |
| @@ -0,0 +1,83 @@ |
| +// 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_TASK_RUNNER_H_ |
| +#define REMOTING_BASE_AUTO_THREAD_TASK_RUNNER_H_ |
| + |
| +#include "base/basictypes.h" |
| +#include "base/callback.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/message_loop.h" |
| +#include "base/single_thread_task_runner.h" |
| + |
| +class MessageLoop; |
| + |
| +namespace remoting { |
| + |
| +// This class provides automatic life time management for |
| +// |SingleThreadTaskRunner|. The task runner is stopped when the last reference |
| +// to |AutoThreadTaskRunner| is dropped. |
|
Wez
2012/08/30 23:56:43
This still isn't true, though; the task runner is
alexeypa (please no reviews)
2012/08/31 19:57:36
Done.
|
| +class AutoThreadTaskRunner : public base::SingleThreadTaskRunner { |
|
Sergey Ulanov
2012/08/31 01:25:18
can you please add some unittests for this class?
alexeypa (please no reviews)
2012/08/31 19:57:36
Done.
|
| + public: |
| + // Constructs an instance of |AutoThreadTaskRunner| wrapping |task_runner|. |
| + // |stop_callback| is called (on arbitraty thread) when the last reference to |
| + // the object is dropped. |
| + explicit AutoThreadTaskRunner( |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| + AutoThreadTaskRunner(scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| + const base::Closure& stop_callback); |
| + |
| + // TODO(alexeypa): Remove the |parent| reference once Thread class supports |
| + // stopping the thread's message loop and joining the thread separately. |
|
Wez
2012/08/30 23:56:43
nit: Add a reference to crbug.com/145856 here?
alexeypa (please no reviews)
2012/08/31 19:57:36
Done.
|
| + // |
| + // Background: currently the only legitimate way of stopping a thread is to |
| + // call Thread::Stop() from the same thread that started it. Thread::Stop() |
| + // will stop the thread message loop by posting a private task and join |
| + // the thread. Thread::Stop() verifies that it is called from the right thread |
| + // and that the message loop has been stopped by the private task mentioned |
| + // above. |
|
Wez
2012/08/30 23:56:43
nit: You only need the first sentence of this comm
alexeypa (please no reviews)
2012/08/31 19:57:36
I think it deserves a verbose comment, given the n
|
| + // |
| + // Until Thread::Stop() is split in two separate operations, it should not be |
| + // called while any objects use it. This is achieved by keeping a reference to |
| + // the parent thread's task runner. Since Thread::Stop() is called after |
| + // exiting the parent loop, keeping a reference to it gives enough guaratee. |
|
Wez
2012/08/30 23:56:43
typo: guarantee
alexeypa (please no reviews)
2012/08/31 19:57:36
Done.
|
| + // |parent| should itself be an AutoThreadTaskRunner managed thread, to |
| + // guarantee that it remains alive long enough to perform the Stop(). |
|
Wez
2012/08/30 23:56:43
Suggest rewording:
"To work around this we require
alexeypa (please no reviews)
2012/08/31 19:57:36
This sounds confusing to me. Check out my variant.
|
| + AutoThreadTaskRunner(scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| + scoped_refptr<base::SingleThreadTaskRunner> parent); |
|
Wez
2012/08/30 23:56:43
Do we ever need to pass a non-AutoThreadTaskRunner
alexeypa (please no reviews)
2012/08/31 19:57:36
Done.
|
| + AutoThreadTaskRunner(scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| + scoped_refptr<base::SingleThreadTaskRunner> parent, |
| + const base::Closure& stop_callback); |
| + |
| + // SingleThreadTaskRunner implementation |
| + virtual bool PostDelayedTask(const tracked_objects::Location& from_here, |
| + const base::Closure& task, |
| + base::TimeDelta delay) OVERRIDE; |
| + virtual bool PostNonNestableDelayedTask( |
| + const tracked_objects::Location& from_here, |
| + const base::Closure& task, |
| + base::TimeDelta delay) OVERRIDE; |
| + virtual bool RunsTasksOnCurrentThread() const OVERRIDE; |
| + |
| + private: |
| + friend class base::DeleteHelper<AutoThreadTaskRunner>; |
| + |
| + virtual ~AutoThreadTaskRunner(); |
| + |
| + // An reference to the parent message loop to keep it alive while |
| + // |task_runner_| is running. |
| + scoped_refptr<base::SingleThreadTaskRunner> parent_; |
| + |
| + // This callback quits |task_runner_|. It can be run on any thread. |
| + base::Closure stop_callback_; |
| + |
| + // The wrapped task runner. |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(AutoThreadTaskRunner); |
| +}; |
| + |
| +} // namespace remoting |
| + |
| +#endif // REMOTING_BASE_AUTO_THREAD_TASK_RUNNER_H_ |