Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(688)

Side by Side Diff: services/nacl/content_handler_main_nonsfi_pexe.cc

Issue 1382713002: Creating a pexe content handler to translate and run pexes. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Added Mojom interface to communicate with translation nexes Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 <fcntl.h>
6
7 #include "base/files/file_util.h"
8 #include "mojo/application/application_runner_chromium.h"
9 #include "mojo/application/content_handler_factory.h"
10 #include "mojo/data_pipe_utils/data_pipe_utils.h"
11 #include "mojo/message_pump/message_pump_mojo.h"
12 #include "mojo/nacl/nonsfi/nexe_launcher_nonsfi.h"
13 #include "mojo/public/c/system/main.h"
14 #include "mojo/public/cpp/application/application_impl.h"
15 #include "services/nacl/pnacl_compile.mojom.h"
16 #include "services/nacl/pnacl_link.mojom.h"
17
18 namespace nacl {
19 namespace content_handler {
20 namespace {
21
22 // RunnableImpl and MakeRunnable lifted from
Mark Seaborn 2015/10/27 17:30:21 Is this different from base::Bind() (from base/bin
Sean Klein 2015/10/28 17:02:41 Nope -- Removed. Now I know what base::Bind() does
23 // mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc.
24 // They are used to turn functions into callbacks easily.
25 template <typename Method, typename Class>
26 class RunnableImpl {
27 public:
28 RunnableImpl(Method method, Class instance)
29 : method_(method), instance_(instance) {}
30 template <typename... Args>
31 void Run(Args... args) const {
32 (instance_->*method_)(args...);
33 }
34
35 private:
36 Method method_;
37 Class instance_;
38 };
39
40 template <typename Method, typename Class>
41 RunnableImpl<Method, Class> MakeRunnable(Method method, Class object) {
42 return RunnableImpl<Method, Class>(method, object);
43 }
44
45 class CompilerUI {
Mark Seaborn 2015/10/27 17:30:21 Does "UI" mean "user interface" here?
Sean Klein 2015/10/28 17:02:41 Yeah, I used this naming scheme (https://cs.corp.g
46 public:
47 explicit CompilerUI(mojo::ScopedMessagePipeHandle handle)
48 : callback_(MakeRunnable(&CompilerUI::Output, this)) {
49 compiler_.Bind(mojo::InterfacePtrInfo<mojo::nacl::PexeCompiler>(
50 handle.Pass(), 0u));
51 }
52
53 // Synchronous method to compile pexe into object file.
54 mojo::String CompilePexe(mojo::String pexe_file_path) {
55 compiler_->PexeCompile(pexe_file_path, callback_);
Mark Seaborn 2015/10/27 17:30:20 Hmm, isn't invoking a method synchronously a commo
Sean Klein 2015/10/28 17:02:41 Done -- this also removed the need for base::Bind.
56 compiler_.WaitForIncomingResponse();
57 return output_;
58 }
59
60 private:
61 mojo::nacl::PexeCompilerPtr compiler_;
62 mojo::Callback<void(mojo::String)> callback_;
63 mojo::String output_;
64 void Output(mojo::String output) { output_ = output; }
65 };
66
67 class LinkerUI {
68 public:
69 explicit LinkerUI(mojo::ScopedMessagePipeHandle handle)
70 : callback_(MakeRunnable(&LinkerUI::Output, this)) {
71 linker_.Bind(mojo::InterfacePtrInfo<mojo::nacl::PexeLinker>(
72 handle.Pass(), 0u));
73 }
74
75 // Synchronous method to link object file into nexe.
76 mojo::String LinkPexe(mojo::String object_file_path) {
77 linker_->PexeLink(object_file_path, callback_);
78 linker_.WaitForIncomingResponse();
79 return output_;
80 }
81
82 private:
83 mojo::nacl::PexeLinkerPtr linker_;
84 mojo::Callback<void(mojo::String)> callback_;
85 mojo::String output_;
86 void Output(mojo::String output) { output_ = output; }
87 };
88
89 } // namespace anonymous
90
91 class PexeContentHandler : public mojo::ApplicationDelegate,
92 public mojo::ContentHandlerFactory::Delegate {
93 public:
94 PexeContentHandler() : content_handler_factory_(this) {}
95
96 private:
97 // Overridden from ApplicationDelegate:
98 void Initialize(mojo::ApplicationImpl* app) override {
99 app->ConnectToService("mojo:pnacl_compile", &compiler_init_);
100 app->ConnectToService("mojo:pnacl_link", &linker_init_);
101 }
102
103 // Overridden from ApplicationDelegate:
104 bool ConfigureIncomingConnection(
105 mojo::ApplicationConnection* connection) override {
106 connection->AddService(&content_handler_factory_);
107 return true;
108 }
109
110 // Overridden from ContentHandlerFactory::ManagedDelegate:
111 void RunApplication(
112 mojo::InterfaceRequest<mojo::Application> application_request,
113 mojo::URLResponsePtr response) override {
114 // Needed to use Mojo interfaces on this thread.
115 base::MessageLoop loop(mojo::common::MessagePumpMojo::Create());
116 // Create temporary file for pexe
117 base::FilePath pexe_file_path;
118 FILE* pexe_fp = CreateAndOpenTemporaryFile(&pexe_file_path);
119 if (!pexe_fp)
120 LOG(FATAL) << "Could not create temporary file for pexe";
121 // Acquire the pexe.
122 if (!mojo::common::BlockingCopyToFile(response->body.Pass(), pexe_fp))
123 LOG(FATAL) << "Could not copy pexe to file";
124 if (fclose(pexe_fp))
125 LOG(FATAL) << "Could not close pexe file";
126
127 // Compile the pexe into an object file
128 mojo::ScopedMessagePipeHandle parent_compile_pipe;
129 mojo::ScopedMessagePipeHandle child_compile_pipe;
130 if (CreateMessagePipe(nullptr, &parent_compile_pipe, &child_compile_pipe) !=
131 MOJO_RESULT_OK)
132 LOG(FATAL) << "Could not create message pipe to compiler";
133 compiler_init_->PexeCompilerStart(child_compile_pipe.Pass());
134
135 // Communicate with the compiler using a mojom interface.
136 CompilerUI compiler_ui(parent_compile_pipe.Pass());
137 mojo::String object_file = compiler_ui.CompilePexe(pexe_file_path.value());
138
139 // Link the object file into a nexe
140 mojo::ScopedMessagePipeHandle parent_link_pipe;
141 mojo::ScopedMessagePipeHandle child_link_pipe;
142 if (CreateMessagePipe(nullptr, &parent_link_pipe, &child_link_pipe) !=
143 MOJO_RESULT_OK)
144 LOG(FATAL) << "Could not create message pipe to linker";
145 linker_init_->PexeLinkerStart(child_link_pipe.Pass());
146
147 // Communicate with the linker using a mojom interface.
148 LinkerUI linker_ui(parent_link_pipe.Pass());
149 mojo::String nexe_file = linker_ui.LinkPexe(object_file);
150
151 // Open the nexe file and launch it (with our mojo handle)
152 int nexe_fd = open(nexe_file.get().c_str(), O_RDONLY);
153 if (unlink(nexe_file.get().c_str()))
154 LOG(FATAL) << "Could not unlink temporary nexe file";
155 if (nexe_fd < 0)
156 LOG(FATAL) << "Could not open nexe object file";
157
158 // Pass the handle connecting us with mojo_shell to the nexe.
159 MojoHandle handle = application_request.PassMessagePipe().release().value();
160 ::nacl::MojoLaunchNexeNonsfi(nexe_fd, handle,
161 false /* enable_translation_irt */);
162 }
163
164 private:
165 mojo::ContentHandlerFactory content_handler_factory_;
166 mojo::nacl::PexeCompilerInitPtr compiler_init_;
167 mojo::nacl::PexeLinkerInitPtr linker_init_;
168
169 DISALLOW_COPY_AND_ASSIGN(PexeContentHandler);
170 };
171
172 } // namespace content_handler
173 } // namespace nacl
174
175 MojoResult MojoMain(MojoHandle application_request) {
176 mojo::ApplicationRunnerChromium runner(
177 new nacl::content_handler::PexeContentHandler());
178 return runner.Run(application_request);
179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698