diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-04 22:27:43 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-04 22:27:43 +0000 |
commit | ef948e69b97c179af5eb69ae318714052230df4f (patch) | |
tree | cc76efb6983b1a5868f26769fb654185880f2805 /remoting/base/auto_thread_task_runner.h | |
parent | 38091251bfc38e7ae748edbf66b13dd360f68bb4 (diff) | |
download | chromium_src-ef948e69b97c179af5eb69ae318714052230df4f.zip chromium_src-ef948e69b97c179af5eb69ae318714052230df4f.tar.gz chromium_src-ef948e69b97c179af5eb69ae318714052230df4f.tar.bz2 |
[Chromoting] Introducing refcount-based life time management of the message loops in the service (daemon) and me2me host (network) processes.
This CL introduces AutoMessageLoop wrapper that provides control over life time of a message loop via scoped_refptr references. This scheme is useful in the cases when shutdown code has to run on a particular thread or when the OS requires resources (such as windows) to be freed before exiting a message loop.
The CL switches threads, owned by remoting::HostService, remoting::HostProcess and remoting::ChromotingHostContext, to refcount-based lifetime management. This change required updating tear-down sequences in remoting_me2me_host and the host plugin code.
BUG=134694
Review URL: https://chromiumcodereview.appspot.com/10829467
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154827 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/base/auto_thread_task_runner.h')
-rw-r--r-- | remoting/base/auto_thread_task_runner.h | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/remoting/base/auto_thread_task_runner.h b/remoting/base/auto_thread_task_runner.h new file mode 100644 index 0000000..bc4fd7c --- /dev/null +++ b/remoting/base/auto_thread_task_runner.h @@ -0,0 +1,87 @@ +// 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 { + +// A wrapper around |SingleThreadTaskRunner| that provides automatic lifetime +// management, by invoking a caller-supplied callback when no more references +// remain, that can stop the wrapped task runner. The caller may also provide a +// reference to a parent |AutoThreadTaskRunner| to express dependencies between +// child and parent thread lifetimes. +class AutoThreadTaskRunner : public base::SingleThreadTaskRunner { + 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. + // See http://crbug.com/145856. + // + // 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. + // + // Due to NPAPI/PPAPI limitations tasks cannot be posted to the main message + // loop when the host plugin is being shut down. This presents a challenge + // since Thread::Stop() cannot be called from an arbitrary thread. To work + // around this we keep a reference to the parent task runner (typically + // the one that started the thread) to keep it alive while the worker thread + // is in use. Thread::Stop() is called to stop the worker thread when + // the parent task runner exits. + AutoThreadTaskRunner(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + scoped_refptr<AutoThreadTaskRunner> parent); + AutoThreadTaskRunner(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + scoped_refptr<AutoThreadTaskRunner> 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<AutoThreadTaskRunner> 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_ |