in_process_dynamic_service_runner.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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" 923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/location.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h" 1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/public/platform/native/gles2_impl_chromium_sync_point_thunks.h" 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/public/platform/native/gles2_impl_chromium_texture_mailbox_thunks.h" 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/public/platform/native/gles2_impl_thunks.h" 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/public/platform/native/gles2_thunks.h" 16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "mojo/public/platform/native/system_thunks.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace mojo { 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace shell { 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace { 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)template <typename Thunks> 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool SetThunks(Thunks (*make_thunks)(), 256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const char* function_name, 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::ScopedNativeLibrary* library) { 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) typedef size_t (*SetThunksFn)(const Thunks* thunks); 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SetThunksFn set_thunks = 296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) reinterpret_cast<SetThunksFn>(library->GetFunctionPointer(function_name)); 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!set_thunks) 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Thunks thunks = make_thunks(); 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) size_t expected_size = set_thunks(&thunks); 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (expected_size > sizeof(Thunks)) { 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) LOG(ERROR) << "Invalid app library: expected " << function_name 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) << " to return thunks of size: " << expected_size; 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return true; 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)InProcessDynamicServiceRunner::InProcessDynamicServiceRunner( 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Context* context) { 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)InProcessDynamicServiceRunner::~InProcessDynamicServiceRunner() { 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (thread_) { 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_->HasBeenStarted()); 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(!thread_->HasBeenJoined()); 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) thread_->Join(); 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // It is important to let the thread exit before unloading the DSO because 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the library may have registered thread-local data and destructors to run 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // on thread termination. 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) app_library_.Reset(base::NativeLibrary()); 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InProcessDynamicServiceRunner::Start( 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath& app_path, 620de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) ScopedMessagePipeHandle service_handle, 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::Closure& app_completed_callback) { 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_path_ = app_path; 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!service_handle_.is_valid()); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) service_handle_ = service_handle.Pass(); 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(app_completed_callback_runner_.is_null()); 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) app_completed_callback_runner_ = base::Bind(&base::TaskRunner::PostTask, 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::MessageLoopProxy::current(), 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FROM_HERE, 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) app_completed_callback); 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(!thread_); 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) thread_.reset(new base::DelegateSimpleThread(this, "app_thread")); 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) thread_->Start(); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InProcessDynamicServiceRunner::Run() { 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DVLOG(2) << "Loading/running Mojo app in process from library: " 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << app_path_.value(); 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) do { 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::NativeLibraryLoadError error; 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) app_library_.Reset(base::LoadNativeLibrary(app_path_, &error)); 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!app_library_.is_valid()) { 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(ERROR) << "Failed to load app library (error: " << error.ToString() 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch << ")"; 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!SetThunks( 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &MojoMakeSystemThunks, "MojoSetSystemThunks", &app_library_)) { 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // In the component build, Mojo Apps link against mojo_system_impl. 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if !defined(COMPONENT_BUILD) 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Strictly speaking this is not required, but it's very unusual to have 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // an app that doesn't require the basic system library. 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(WARNING) << "MojoSetSystemThunks not found in app library"; 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (SetThunks(&MojoMakeGLES2ControlThunks, 1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "MojoSetGLES2ControlThunks", 1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &app_library_)) { 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If we have the control thunks, we probably also have the 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // GLES2 implementation thunks. 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!SetThunks(&MojoMakeGLES2ImplThunks, 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "MojoSetGLES2ImplThunks", 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &app_library_)) { 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // In the component build, Mojo Apps link against mojo_gles2_impl. 1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if !defined(COMPONENT_BUILD) 1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Warn on this really weird case: The library requires the GLES2 1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // control functions, but doesn't require the GLES2 implementation. 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG(WARNING) << app_path_.value() 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << " has MojoSetGLES2ControlThunks, " 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "but doesn't have MojoSetGLES2ImplThunks."; 1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif 1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If the application is using GLES2 extension points, register those 1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // thunks. Applications may use or not use any of these, so don't warn if 1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // they are missing. 1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SetThunks(MojoMakeGLES2ImplChromiumTextureMailboxThunks, 1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "MojoSetGLES2ImplChromiumTextureMailboxThunks", 1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &app_library_); 1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SetThunks(MojoMakeGLES2ImplChromiumSyncPointThunks, 1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "MojoSetGLES2ImplChromiumSyncPointThunks", 1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &app_library_); 1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Unlike system thunks, we don't warn on a lack of GLES2 thunks because 1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // not everything is a visual app. 1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef MojoResult (*MojoMainFunction)(MojoHandle); 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MojoMainFunction main_function = reinterpret_cast<MojoMainFunction>( 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) app_library_.GetFunctionPointer("MojoMain")); 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!main_function) { 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG(ERROR) << "Entrypoint MojoMain not found: " << app_path_.value(); 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |MojoMain()| takes ownership of the service handle. 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MojoResult result = main_function(service_handle_.release().value()); 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result < MOJO_RESULT_OK) 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "MojoMain returned an error: " << result; 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } while (false); 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci app_completed_callback_runner_.Run(); 14923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) app_completed_callback_runner_.Reset(); 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace shell 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace mojo 154