Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "mojo/shell/service_manager.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/callback_helpers.h" | |
| 9 #include "base/command_line.h" | |
| 10 #include "base/file_util.h" | |
| 11 #include "base/scoped_native_library.h" | |
| 12 #include "base/threading/simple_thread.h" | |
| 13 #include "mojo/public/bindings/lib/remote_ptr.h" | |
| 14 #include "mojo/shell/context.h" | |
| 15 #include "mojo/shell/switches.h" | |
| 16 #include "mojom/shell.h" | |
| 17 | |
| 18 typedef MojoResult (*MojoMainFunction)(MojoHandle pipe); | |
| 19 | |
| 20 namespace mojo { | |
| 21 namespace shell { | |
| 22 | |
| 23 class ServiceManager::Service | |
| 24 : public ::shell::ShellStub, | |
| 25 public Loader::Delegate, | |
| 26 public base::DelegateSimpleThread::Delegate { | |
| 27 public: | |
| 28 Service(ServiceManager* manager, const GURL& url) | |
| 29 : manager_(manager), | |
| 30 url_(url), | |
| 31 weak_factory_(this) { | |
| 32 base::AutoLock lock(lock_); | |
| 33 ScopedMessagePipeHandle shell_handle; | |
| 34 CreateMessagePipe(&shell_handle, &service_handle_); | |
| 35 shell_client_.reset(shell_handle.Pass()); | |
| 36 shell_client_.SetPeer(this); | |
| 37 request_ = manager_->context_->loader()->Load(url_, this); | |
| 38 } | |
| 39 | |
| 40 virtual ~Service() {} | |
| 41 | |
| 42 void ConnectToClient(ScopedMessagePipeHandle handle) { | |
| 43 if (handle.is_valid()) | |
| 44 shell_client_->Connect(handle.Pass()); | |
| 45 } | |
| 46 | |
| 47 virtual void Connect(const mojo::String& url, | |
| 48 ScopedMessagePipeHandle client_pipe) MOJO_OVERRIDE { | |
| 49 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass()); | |
| 50 } | |
| 51 | |
| 52 private: | |
| 53 // From Loader::Delegate. | |
| 54 virtual void DidCompleteLoad(const GURL& app_url, | |
| 55 const base::FilePath& app_path) OVERRIDE { | |
| 56 base::AutoLock lock(lock_); | |
| 57 app_path_ = app_path; | |
| 58 ack_closure_ = | |
| 59 base::Bind(&Service::AppCompleted, weak_factory_.GetWeakPtr()); | |
| 60 thread_.reset(new base::DelegateSimpleThread(this, "app_thread")); | |
| 61 thread_->Start(); | |
| 62 } | |
| 63 | |
| 64 // From base::DelegateSimpleThread::Delegate. | |
| 65 virtual void Run() OVERRIDE { | |
| 66 base::AutoLock lock(lock_); | |
|
abarth-chromium
2013/12/10 01:06:03
So, this lock is held as long as the app is runnin
DaveMoore
2013/12/10 03:00:45
You are right. It was left in accidentally
On 2013
| |
| 67 base::ScopedClosureRunner app_deleter( | |
| 68 base::Bind(base::IgnoreResult(&base::DeleteFile), app_path_, false)); | |
| 69 base::ScopedNativeLibrary app_library( | |
| 70 base::LoadNativeLibrary(app_path_, NULL)); | |
| 71 if (!app_library.is_valid()) { | |
| 72 LOG(ERROR) << "Failed to load library: " << app_path_.value().c_str(); | |
| 73 return; | |
| 74 } | |
| 75 | |
| 76 MojoMainFunction main_function = reinterpret_cast<MojoMainFunction>( | |
| 77 app_library.GetFunctionPointer("MojoMain")); | |
| 78 if (!main_function) { | |
| 79 LOG(ERROR) << "Entrypoint MojoMain not found."; | |
| 80 return; | |
| 81 } | |
| 82 | |
| 83 // |MojoMain()| takes ownership of the app handle. | |
| 84 MojoResult result = main_function(service_handle_.release().value()); | |
| 85 if (result < MOJO_RESULT_OK) { | |
| 86 LOG(ERROR) << "MojoMain returned an error: " << result; | |
| 87 return; | |
| 88 } | |
| 89 manager_->context_->task_runners()->ui_runner()->PostTask( | |
| 90 FROM_HERE, | |
| 91 ack_closure_); | |
| 92 } | |
| 93 | |
| 94 void AppCompleted() { | |
| 95 thread_->Join(); | |
| 96 thread_.reset(); | |
| 97 } | |
| 98 | |
| 99 base::Lock lock_; | |
| 100 ServiceManager* manager_; | |
| 101 GURL url_; | |
| 102 mojo::RemotePtr<::shell::ShellClient> shell_client_; | |
| 103 base::FilePath app_path_; | |
| 104 base::Closure ack_closure_; | |
| 105 scoped_ptr<Loader::Job> request_; | |
| 106 scoped_ptr<base::DelegateSimpleThread> thread_; | |
| 107 ScopedMessagePipeHandle service_handle_; | |
| 108 | |
| 109 base::WeakPtrFactory<Service> weak_factory_; | |
| 110 | |
| 111 DISALLOW_COPY_AND_ASSIGN(Service); | |
| 112 }; | |
| 113 | |
| 114 ServiceManager::ServiceManager(Context* context) : context_(context) { | |
| 115 } | |
| 116 | |
| 117 ServiceManager::~ServiceManager() { | |
| 118 } | |
| 119 | |
| 120 void ServiceManager::Connect(const GURL& url, | |
| 121 ScopedMessagePipeHandle client_handle) { | |
| 122 GURL app_url = url; | |
| 123 if (url.scheme() == "mojo") { | |
| 124 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
| 125 std::string origin = command_line.GetSwitchValueASCII(switches::kOrigin); | |
| 126 std::string lib("lib" + url.ExtractFileName() + ".so"); | |
|
abarth-chromium
2013/12/10 01:06:03
This won't work on Window or Mac.
DaveMoore
2013/12/10 03:00:45
You're right...it won't. I'll take a look at that
| |
| 127 app_url = GURL(origin + std::string("/") + lib); | |
| 128 } | |
| 129 base::AutoLock lock(service_map_lock_); | |
|
abarth-chromium
2013/12/10 01:06:03
I don't understand this lock either. Isn't this f
DaveMoore
2013/12/10 03:00:45
At one point I was thinking that each Service migh
| |
| 130 ServiceMap::const_iterator service_it = url_to_service_.find(app_url); | |
| 131 Service* service; | |
| 132 if (service_it != url_to_service_.end()) { | |
| 133 service = service_it->second; | |
| 134 } else { | |
| 135 service = new Service(this, app_url); | |
| 136 url_to_service_[app_url] = service; | |
| 137 } | |
| 138 service->ConnectToClient(client_handle.Pass()); | |
| 139 } | |
| 140 | |
| 141 } // namespace shell | |
| 142 } // namespace mojo | |
| OLD | NEW |