in_process_dynamic_service_runner.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/shell/in_process_dynamic_service_runner.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/callback_helpers.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/file_util.h" 1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/location.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h" 1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/scoped_native_library.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace mojo { 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace shell { 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)InProcessDynamicServiceRunner::InProcessDynamicServiceRunner( 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Context* /*context*/) 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : thread_(this, "app_thread") { 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)InProcessDynamicServiceRunner::~InProcessDynamicServiceRunner() { 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (thread_.HasBeenStarted()) { 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!thread_.HasBeenJoined()); 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) thread_.Join(); 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InProcessDynamicServiceRunner::Start( 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath& app_path, 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedShellHandle service_handle, 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::Closure& app_completed_callback) { 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_path_ = app_path; 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!service_handle_.is_valid()); 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) service_handle_ = service_handle.Pass(); 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(app_completed_callback_runner_.is_null()); 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) app_completed_callback_runner_ = base::Bind(&base::TaskRunner::PostTask, 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::MessageLoopProxy::current(), 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FROM_HERE, 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) app_completed_callback); 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!thread_.HasBeenStarted()); 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) thread_.Start(); 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InProcessDynamicServiceRunner::Run() { 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(2) << "Loading/running Mojo app from " << app_path_.value() 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " in process"; 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedClosureRunner app_deleter( 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(base::IgnoreResult(&base::DeleteFile), app_path_, false)); 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) do { 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string load_error; 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedNativeLibrary app_library( 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::LoadNativeLibrary(app_path_, &load_error)); 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!app_library.is_valid()) { 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Failed to load library (error: " << load_error << ")"; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef MojoResult (*MojoMainFunction)(MojoHandle); 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MojoMainFunction main_function = reinterpret_cast<MojoMainFunction>( 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_library.GetFunctionPointer("MojoMain")); 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!main_function) { 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Entrypoint MojoMain not found"; 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |MojoMain()| takes ownership of the service handle. 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MojoResult result = main_function(service_handle_.release().value()); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result < MOJO_RESULT_OK) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "MojoMain returned an error: " << result; 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } while (false); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool success = app_completed_callback_runner_.Run(); 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) app_completed_callback_runner_.Reset(); 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) LOG_IF(ERROR, !success) << "Failed post run app_completed_callback"; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace shell 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace mojo 86