summaryrefslogtreecommitdiffstats
path: root/mojo/shell/public/cpp/lib/app_lifetime_helper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/shell/public/cpp/lib/app_lifetime_helper.cc')
-rw-r--r--mojo/shell/public/cpp/lib/app_lifetime_helper.cc94
1 files changed, 94 insertions, 0 deletions
diff --git a/mojo/shell/public/cpp/lib/app_lifetime_helper.cc b/mojo/shell/public/cpp/lib/app_lifetime_helper.cc
new file mode 100644
index 0000000..0772412a
--- /dev/null
+++ b/mojo/shell/public/cpp/lib/app_lifetime_helper.cc
@@ -0,0 +1,94 @@
+// Copyright 2015 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.
+
+#include "mojo/shell/public/cpp/app_lifetime_helper.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/shell/public/cpp/application_impl.h"
+
+namespace mojo {
+
+AppRefCount::AppRefCount(
+ AppLifetimeHelper* app_lifetime_helper,
+ scoped_refptr<base::SingleThreadTaskRunner> app_task_runner)
+ : app_lifetime_helper_(app_lifetime_helper),
+ app_task_runner_(app_task_runner) {
+}
+
+AppRefCount::~AppRefCount() {
+#ifndef NDEBUG
+ // Ensure that this object is used on only one thread at a time, or else there
+ // could be races where the object is being reset on one thread and cloned on
+ // another.
+ if (clone_task_runner_) {
+ DCHECK(clone_task_runner_->BelongsToCurrentThread());
+ }
+#endif
+
+ if (app_task_runner_->BelongsToCurrentThread()) {
+ app_lifetime_helper_->Release();
+ return;
+ }
+
+ app_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&AppLifetimeHelper::Release,
+ base::Unretained(app_lifetime_helper_)));
+}
+
+scoped_ptr<AppRefCount> AppRefCount::Clone() {
+ if (app_task_runner_->BelongsToCurrentThread()) {
+ app_lifetime_helper_->AddRef();
+ } else {
+ app_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&AppLifetimeHelper::AddRef,
+ base::Unretained(app_lifetime_helper_)));
+ }
+
+#ifndef NDEBUG
+ // Ensure that this object is used on only one thread at a time, or else there
+ // could be races where the object is being reset on one thread and cloned on
+ // another.
+ if (clone_task_runner_) {
+ DCHECK(clone_task_runner_->BelongsToCurrentThread());
+ } else {
+ clone_task_runner_ = base::MessageLoop::current()->task_runner();
+ }
+#endif
+
+ return make_scoped_ptr(new AppRefCount(
+ app_lifetime_helper_, app_task_runner_));
+}
+
+AppLifetimeHelper::AppLifetimeHelper(ApplicationImpl* app)
+ : app_(app), ref_count_(0) {
+}
+
+AppLifetimeHelper::~AppLifetimeHelper() {
+}
+
+scoped_ptr<AppRefCount> AppLifetimeHelper::CreateAppRefCount() {
+ AddRef();
+ return make_scoped_ptr(new AppRefCount(
+ this, base::MessageLoop::current()->task_runner()));
+}
+
+void AppLifetimeHelper::AddRef() {
+ ref_count_++;
+}
+
+void AppLifetimeHelper::Release() {
+ if (!--ref_count_) {
+ if (app_)
+ app_->Quit();
+ }
+}
+
+void AppLifetimeHelper::OnQuit() {
+ app_ = nullptr;
+}
+
+} // namespace mojo