Index: mojo/application/run_application.cc |
diff --git a/mojo/application/run_application.cc b/mojo/application/run_application.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bee1f417939a36b57b26c3c4e50fae71f379565b |
--- /dev/null |
+++ b/mojo/application/run_application.cc |
@@ -0,0 +1,96 @@ |
+// Copyright 2016 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/public/cpp/application/run_application.h" |
+ |
+#include <memory> |
+ |
+#include "base/at_exit.h" |
+#include "base/command_line.h" |
+#include "base/debug/stack_trace.h" |
+#include "base/message_loop/message_loop.h" |
+#include "base/threading/thread_local_storage.h" |
+#include "build/build_config.h" |
+#include "mojo/message_pump/message_pump_mojo.h" |
+#include "mojo/public/cpp/application/application_impl_base.h" |
+#include "mojo/public/cpp/system/message_pipe.h" |
+ |
+namespace mojo { |
+ |
+namespace { |
+ |
+base::ThreadLocalStorage::StaticSlot g_current_result_holder = TLS_INITIALIZER; |
+ |
+// We store a pointer to a |ResultHolder|, which just stores a |MojoResult|, in |
+// TLS so that |TerminateApplication()| can provide the result that |
+// |RunApplication()| will return. (The |ResultHolder| is just on |
+// |RunApplication()|'s stack.) |
+struct ResultHolder { |
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) |
+ bool is_set = false; |
+#endif |
+ // TODO(vtl): The default result should probably be |MOJO_RESULT_UNKNOWN|, but |
+ // |ApplicationRunnerChromium| always returned |MOJO_RESULT_OK|. |
vardhan
2016/05/25 17:59:54
would anything break if we changed it now?
viettrungluu
2016/05/25 18:10:07
Yes, see CL description.
|
+ MojoResult result = MOJO_RESULT_OK; |
+}; |
+ |
+} // namespace |
+ |
+MojoResult RunMainApplication(MojoHandle application_request_handle, |
+ ApplicationImplBase* application_impl) { |
+ base::CommandLine::Init(0, nullptr); |
+ base::AtExitManager at_exit; |
+ |
+ g_current_result_holder.Initialize(nullptr); |
+ |
+#if !defined(NDEBUG) && !defined(OS_NACL) |
+ base::debug::EnableInProcessStackDumping(); |
+#endif |
+ |
+ return RunApplication(application_request_handle, application_impl); |
+} |
+ |
+MojoResult RunApplication(MojoHandle application_request_handle, |
+ ApplicationImplBase* application_impl) { |
+ DCHECK(!g_current_result_holder.Get()); |
+ |
+ ResultHolder result_holder; |
+ g_current_result_holder.Set(&result_holder); |
+ |
+ std::unique_ptr<base::MessageLoop> loop; |
+ // TODO(vtl): Support other types of message loops. (That's why I'm leaving |
+ // |loop| as a unique_ptr.) |
+ loop.reset(new base::MessageLoop(common::MessagePumpMojo::Create())); |
+ application_impl->Bind(InterfaceRequest<Application>( |
+ MakeScopedHandle(MessagePipeHandle(application_request_handle)))); |
+ loop->Run(); |
+ |
+ g_current_result_holder.Set(nullptr); |
+ |
+ // TODO(vtl): We'd like to enable the following assertion, but we quit the |
+ // current message loop directly in various places. |
+ // DCHECK(result_holder.is_set); |
+ |
+ return result_holder.result; |
+} |
+ |
+void TerminateMainApplication(MojoResult result) { |
+ TerminateApplication(result); |
+} |
+ |
+void TerminateApplication(MojoResult result) { |
+ DCHECK(base::MessageLoop::current()->is_running()); |
+ base::MessageLoop::current()->Quit(); |
+ |
+ ResultHolder* result_holder = |
+ static_cast<ResultHolder*>(g_current_result_holder.Get()); |
+ DCHECK(result_holder); |
+ DCHECK(!result_holder->is_set); |
+ result_holder->result = result; |
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) |
+ result_holder->is_set = true; |
+#endif |
+} |
+ |
+} // namespace mojo |