summaryrefslogtreecommitdiffstats
path: root/remoting/base/auto_thread_task_runner.h
diff options
context:
space:
mode:
authoralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-04 22:27:43 +0000
committeralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-04 22:27:43 +0000
commitef948e69b97c179af5eb69ae318714052230df4f (patch)
treecc76efb6983b1a5868f26769fb654185880f2805 /remoting/base/auto_thread_task_runner.h
parent38091251bfc38e7ae748edbf66b13dd360f68bb4 (diff)
downloadchromium_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.h87
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_