| OLD | NEW | 
|    1 // Copyright 2016 The Chromium Authors. All rights reserved. |    1 // Copyright 2016 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "mojo/public/cpp/application/run_application.h" |    5 #include "mojo/public/cpp/application/run_application.h" | 
|    6  |    6  | 
|    7 #include <memory> |    7 #include <memory> | 
|    8  |    8  | 
|    9 #include "base/at_exit.h" |    9 #include "base/at_exit.h" | 
|   10 #include "base/command_line.h" |   10 #include "base/command_line.h" | 
|   11 #include "base/debug/stack_trace.h" |   11 #include "base/debug/stack_trace.h" | 
 |   12 #include "base/lazy_instance.h" | 
|   12 #include "base/message_loop/message_loop.h" |   13 #include "base/message_loop/message_loop.h" | 
|   13 #include "base/threading/thread_local_storage.h" |   14 #include "base/threading/thread_local.h" | 
|   14 #include "build/build_config.h" |   15 #include "build/build_config.h" | 
|   15 #include "mojo/application/run_application_options_chromium.h" |   16 #include "mojo/application/run_application_options_chromium.h" | 
|   16 #include "mojo/message_pump/message_pump_mojo.h" |   17 #include "mojo/message_pump/message_pump_mojo.h" | 
|   17 #include "mojo/public/cpp/application/application_impl_base.h" |   18 #include "mojo/public/cpp/application/application_impl_base.h" | 
|   18 #include "mojo/public/cpp/system/message_pipe.h" |   19 #include "mojo/public/cpp/system/message_pipe.h" | 
|   19  |   20  | 
|   20 namespace mojo { |   21 namespace mojo { | 
|   21  |   22  | 
|   22 namespace { |   23 namespace { | 
|   23  |   24  | 
|   24 base::ThreadLocalStorage::StaticSlot g_current_result_holder = TLS_INITIALIZER; |  | 
|   25  |  | 
|   26 // We store a pointer to a |ResultHolder|, which just stores a |MojoResult|, in |   25 // We store a pointer to a |ResultHolder|, which just stores a |MojoResult|, in | 
|   27 // TLS so that |TerminateApplication()| can provide the result that |   26 // TLS so that |TerminateApplication()| can provide the result that | 
|   28 // |RunApplication()| will return. (The |ResultHolder| is just on |   27 // |RunApplication()| will return. (The |ResultHolder| is just on | 
|   29 // |RunApplication()|'s stack.) |   28 // |RunApplication()|'s stack.) | 
|   30 struct ResultHolder { |   29 struct ResultHolder { | 
|   31 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) |   30 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) | 
|   32   bool is_set = false; |   31   bool is_set = false; | 
|   33 #endif |   32 #endif | 
|   34   // TODO(vtl): The default result should probably be |MOJO_RESULT_UNKNOWN|, but |   33   // TODO(vtl): The default result should probably be |MOJO_RESULT_UNKNOWN|, but | 
|   35   // |ApplicationRunnerChromium| always returned |MOJO_RESULT_OK|. |   34   // |ApplicationRunnerChromium| always returned |MOJO_RESULT_OK|. | 
|   36   MojoResult result = MOJO_RESULT_OK; |   35   MojoResult result = MOJO_RESULT_OK; | 
|   37 }; |   36 }; | 
|   38  |   37  | 
 |   38 base::LazyInstance<base::ThreadLocalPointer<ResultHolder>>::Leaky | 
 |   39     g_current_result_holder = LAZY_INSTANCE_INITIALIZER; | 
 |   40  | 
|   39 }  // namespace |   41 }  // namespace | 
|   40  |   42  | 
|   41 MojoResult RunMainApplication(MojoHandle application_request_handle, |  | 
|   42                               ApplicationImplBase* application_impl, |  | 
|   43                               const RunApplicationOptions* options) { |  | 
|   44   base::CommandLine::Init(0, nullptr); |  | 
|   45   base::AtExitManager at_exit; |  | 
|   46  |  | 
|   47   g_current_result_holder.Initialize(nullptr); |  | 
|   48  |  | 
|   49 #if !defined(NDEBUG) && !defined(OS_NACL) |  | 
|   50   base::debug::EnableInProcessStackDumping(); |  | 
|   51 #endif |  | 
|   52  |  | 
|   53   return RunApplication(application_request_handle, application_impl, options); |  | 
|   54 } |  | 
|   55  |  | 
|   56 MojoResult RunApplication(MojoHandle application_request_handle, |   43 MojoResult RunApplication(MojoHandle application_request_handle, | 
|   57                           ApplicationImplBase* application_impl, |   44                           ApplicationImplBase* application_impl, | 
|   58                           const RunApplicationOptions* options) { |   45                           const RunApplicationOptions* options) { | 
|   59   DCHECK(!g_current_result_holder.Get()); |   46   DCHECK(!g_current_result_holder.Pointer()->Get()); | 
|   60  |   47  | 
|   61   ResultHolder result_holder; |   48   ResultHolder result_holder; | 
|   62   g_current_result_holder.Set(&result_holder); |   49   g_current_result_holder.Pointer()->Set(&result_holder); | 
|   63  |   50  | 
|   64   // Note: If |options| is non-null, it better point to a |   51   // Note: If |options| is non-null, it better point to a | 
|   65   // |RunApplicationOptionsChromium|. |   52   // |RunApplicationOptionsChromium|. | 
|   66   base::MessageLoop::Type message_loop_type = |   53   base::MessageLoop::Type message_loop_type = | 
|   67       options |   54       options | 
|   68           ? static_cast<const RunApplicationOptionsChromium*>(options) |   55           ? static_cast<const RunApplicationOptionsChromium*>(options) | 
|   69                 ->message_loop_type |   56                 ->message_loop_type | 
|   70           : base::MessageLoop::TYPE_CUSTOM; |   57           : base::MessageLoop::TYPE_CUSTOM; | 
|   71   std::unique_ptr<base::MessageLoop> loop( |   58   std::unique_ptr<base::MessageLoop> loop( | 
|   72       (message_loop_type == base::MessageLoop::TYPE_CUSTOM) |   59       (message_loop_type == base::MessageLoop::TYPE_CUSTOM) | 
|   73           ? new base::MessageLoop(common::MessagePumpMojo::Create()) |   60           ? new base::MessageLoop(common::MessagePumpMojo::Create()) | 
|   74           : new base::MessageLoop(message_loop_type)); |   61           : new base::MessageLoop(message_loop_type)); | 
|   75   application_impl->Bind(InterfaceRequest<Application>( |   62   application_impl->Bind(InterfaceRequest<Application>( | 
|   76       MakeScopedHandle(MessagePipeHandle(application_request_handle)))); |   63       MakeScopedHandle(MessagePipeHandle(application_request_handle)))); | 
|   77   loop->Run(); |   64   loop->Run(); | 
|   78  |   65  | 
|   79   g_current_result_holder.Set(nullptr); |   66   g_current_result_holder.Pointer()->Set(nullptr); | 
|   80  |   67  | 
|   81   // TODO(vtl): We'd like to enable the following assertion, but we quit the |   68   // TODO(vtl): We'd like to enable the following assertion, but we quit the | 
|   82   // current message loop directly in various places. |   69   // current message loop directly in various places. | 
|   83   // DCHECK(result_holder.is_set); |   70   // DCHECK(result_holder.is_set); | 
|   84  |   71  | 
|   85   return result_holder.result; |   72   return result_holder.result; | 
|   86 } |   73 } | 
|   87  |   74  | 
|   88 void TerminateMainApplication(MojoResult result) { |  | 
|   89   TerminateApplication(result); |  | 
|   90 } |  | 
|   91  |  | 
|   92 void TerminateApplication(MojoResult result) { |   75 void TerminateApplication(MojoResult result) { | 
|   93   DCHECK(base::MessageLoop::current()->is_running()); |   76   DCHECK(base::MessageLoop::current()->is_running()); | 
|   94   base::MessageLoop::current()->Quit(); |   77   base::MessageLoop::current()->Quit(); | 
|   95  |   78  | 
|   96   ResultHolder* result_holder = |   79   ResultHolder* result_holder = g_current_result_holder.Pointer()->Get(); | 
|   97       static_cast<ResultHolder*>(g_current_result_holder.Get()); |  | 
|   98   DCHECK(result_holder); |   80   DCHECK(result_holder); | 
|   99   result_holder->result = result; |   81   result_holder->result = result; | 
|  100 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) |   82 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) | 
|  101   DCHECK(!result_holder->is_set); |   83   DCHECK(!result_holder->is_set); | 
|  102   result_holder->is_set = true; |   84   result_holder->is_set = true; | 
|  103 #endif |   85 #endif | 
|  104 } |   86 } | 
|  105  |   87  | 
|  106 }  // namespace mojo |   88 }  // namespace mojo | 
| OLD | NEW |