Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / mojo / shell / in_process_dynamic_service_runner.cc
index 6bcaa5c..c98ef0f 100644 (file)
@@ -9,23 +9,52 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop_proxy.h"
-#include "base/scoped_native_library.h"
+#include "mojo/public/platform/native/gles2_impl_chromium_sync_point_thunks.h"
+#include "mojo/public/platform/native/gles2_impl_chromium_texture_mailbox_thunks.h"
+#include "mojo/public/platform/native/gles2_impl_thunks.h"
+#include "mojo/public/platform/native/gles2_thunks.h"
 #include "mojo/public/platform/native/system_thunks.h"
 
 namespace mojo {
 namespace shell {
 
+namespace {
+
+template <typename Thunks>
+bool SetThunks(Thunks (*make_thunks)(),
+               const char* function_name,
+               base::ScopedNativeLibrary* library) {
+  typedef size_t (*SetThunksFn)(const Thunks* thunks);
+  SetThunksFn set_thunks =
+      reinterpret_cast<SetThunksFn>(library->GetFunctionPointer(function_name));
+  if (!set_thunks)
+    return false;
+  Thunks thunks = make_thunks();
+  size_t expected_size = set_thunks(&thunks);
+  if (expected_size > sizeof(Thunks)) {
+    LOG(ERROR) << "Invalid app library: expected " << function_name
+               << " to return thunks of size: " << expected_size;
+    return false;
+  }
+  return true;
+}
+}
+
 InProcessDynamicServiceRunner::InProcessDynamicServiceRunner(
-    Context* context)
-    : keep_alive_(context),
-      thread_(this, "app_thread") {
+    Context* context) {
 }
 
 InProcessDynamicServiceRunner::~InProcessDynamicServiceRunner() {
-  if (thread_.HasBeenStarted()) {
-    DCHECK(!thread_.HasBeenJoined());
-    thread_.Join();
+  if (thread_) {
+    DCHECK(thread_->HasBeenStarted());
+    DCHECK(!thread_->HasBeenJoined());
+    thread_->Join();
   }
+
+  // It is important to let the thread exit before unloading the DSO because
+  // the library may have registered thread-local data and destructors to run
+  // on thread termination.
+  app_library_.Reset(base::NativeLibrary());
 }
 
 void InProcessDynamicServiceRunner::Start(
@@ -43,8 +72,9 @@ void InProcessDynamicServiceRunner::Start(
                                               FROM_HERE,
                                               app_completed_callback);
 
-  DCHECK(!thread_.HasBeenStarted());
-  thread_.Start();
+  DCHECK(!thread_);
+  thread_.reset(new base::DelegateSimpleThread(this, "app_thread"));
+  thread_->Start();
 }
 
 void InProcessDynamicServiceRunner::Run() {
@@ -53,37 +83,59 @@ void InProcessDynamicServiceRunner::Run() {
 
   do {
     base::NativeLibraryLoadError error;
-    base::ScopedNativeLibrary app_library(
-        base::LoadNativeLibrary(app_path_, &error));
-    if (!app_library.is_valid()) {
+    app_library_.Reset(base::LoadNativeLibrary(app_path_, &error));
+    if (!app_library_.is_valid()) {
       LOG(ERROR) << "Failed to load app library (error: " << error.ToString()
                  << ")";
       break;
     }
 
-    MojoSetSystemThunksFn mojo_set_system_thunks_fn =
-        reinterpret_cast<MojoSetSystemThunksFn>(app_library.GetFunctionPointer(
-            "MojoSetSystemThunks"));
-    if (mojo_set_system_thunks_fn) {
-      MojoSystemThunks system_thunks = MojoMakeSystemThunks();
-      size_t expected_size = mojo_set_system_thunks_fn(&system_thunks);
-      if (expected_size > sizeof(MojoSystemThunks)) {
-        LOG(ERROR)
-            << "Invalid app library: expected MojoSystemThunks size: "
-            << expected_size;
-        break;
-      }
-    } else {
+    if (!SetThunks(
+            &MojoMakeSystemThunks, "MojoSetSystemThunks", &app_library_)) {
+      // In the component build, Mojo Apps link against mojo_system_impl.
+#if !defined(COMPONENT_BUILD)
       // Strictly speaking this is not required, but it's very unusual to have
       // an app that doesn't require the basic system library.
       LOG(WARNING) << "MojoSetSystemThunks not found in app library";
+#endif
+    }
+
+    if (SetThunks(&MojoMakeGLES2ControlThunks,
+                  "MojoSetGLES2ControlThunks",
+                  &app_library_)) {
+      // If we have the control thunks, we probably also have the
+      // GLES2 implementation thunks.
+      if (!SetThunks(&MojoMakeGLES2ImplThunks,
+                     "MojoSetGLES2ImplThunks",
+                     &app_library_)) {
+        // In the component build, Mojo Apps link against mojo_gles2_impl.
+#if !defined(COMPONENT_BUILD)
+        // Warn on this really weird case: The library requires the GLES2
+        // control functions, but doesn't require the GLES2 implementation.
+        LOG(WARNING) << app_path_.value()
+                     << " has MojoSetGLES2ControlThunks, "
+                        "but doesn't have MojoSetGLES2ImplThunks.";
+#endif
+      }
+
+      // If the application is using GLES2 extension points, register those
+      // thunks. Applications may use or not use any of these, so don't warn if
+      // they are missing.
+      SetThunks(MojoMakeGLES2ImplChromiumTextureMailboxThunks,
+                "MojoSetGLES2ImplChromiumTextureMailboxThunks",
+                &app_library_);
+      SetThunks(MojoMakeGLES2ImplChromiumSyncPointThunks,
+                "MojoSetGLES2ImplChromiumSyncPointThunks",
+                &app_library_);
     }
+    // Unlike system thunks, we don't warn on a lack of GLES2 thunks because
+    // not everything is a visual app.
 
     typedef MojoResult (*MojoMainFunction)(MojoHandle);
     MojoMainFunction main_function = reinterpret_cast<MojoMainFunction>(
-        app_library.GetFunctionPointer("MojoMain"));
+        app_library_.GetFunctionPointer("MojoMain"));
     if (!main_function) {
-      LOG(ERROR) << "Entrypoint MojoMain not found";
+      LOG(ERROR) << "Entrypoint MojoMain not found: " << app_path_.value();
       break;
     }
 
@@ -93,9 +145,8 @@ void InProcessDynamicServiceRunner::Run() {
       LOG(ERROR) << "MojoMain returned an error: " << result;
   } while (false);
 
-  bool success = app_completed_callback_runner_.Run();
+  app_completed_callback_runner_.Run();
   app_completed_callback_runner_.Reset();
-  LOG_IF(ERROR, !success) << "Failed post run app_completed_callback";
 }
 
 }  // namespace shell