OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/nacl/browser/nacl_process_host.h" | 5 #include "components/nacl/browser/nacl_process_host.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 | 187 |
188 void SetCloseOnExec(NaClHandle fd) { | 188 void SetCloseOnExec(NaClHandle fd) { |
189 #if defined(OS_POSIX) | 189 #if defined(OS_POSIX) |
190 int flags = fcntl(fd, F_GETFD); | 190 int flags = fcntl(fd, F_GETFD); |
191 CHECK_NE(flags, -1); | 191 CHECK_NE(flags, -1); |
192 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | 192 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
193 CHECK_EQ(rc, 0); | 193 CHECK_EQ(rc, 0); |
194 #endif | 194 #endif |
195 } | 195 } |
196 | 196 |
197 void CloseFile(base::File file) { | 197 void PostCloseFile(base::File file) { |
198 if (!file.IsValid()) { | |
199 return; | |
200 } | |
201 | |
198 // The base::File destructor will close the file for us. | 202 // The base::File destructor will close the file for us. |
203 content::BrowserThread::GetBlockingPool()->PostTask( | |
204 FROM_HERE, | |
205 base::Bind(&ignore_result<base::File>, base::Passed(&file))); | |
206 } | |
207 | |
208 // The maximum number of resource file handles NaClProcessMsg_Start message | |
209 // can have. Currently IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage | |
210 // is 128 and NaCl sends 5 handles for other purposes, hence 123. | |
211 const size_t kMaxPreOpenResourceFiles = 123; | |
212 | |
213 #if defined(OS_POSIX) | |
214 static_assert(kMaxPreOpenResourceFiles == | |
215 IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage - 5, | |
216 "kMaxPreOpenResourceFiles is not up to date"); | |
217 #endif | |
218 | |
219 void BatchOpenResourceFiles( | |
220 const std::vector<NaClResourcePrefetchRequest>& request_list, | |
221 const base::FilePath& profile_directory, | |
222 base::ProcessHandle target_process, | |
223 std::vector<NaClResourcePrefetchResult>* result_list) { | |
224 if (!result_list) { | |
225 // If output buffer is null, which means there is no resource to be opened. | |
226 // Do nothing, then. | |
227 DCHECK(request_list.empty()); | |
228 return; | |
229 } | |
230 | |
231 NaClBrowserDelegate* browser_delegate = NaClBrowser::GetDelegate(); | |
232 for (size_t i = 0; | |
233 i < request_list.size() && | |
234 result_list->size() < kMaxPreOpenResourceFiles; | |
235 ++i) { | |
236 base::FilePath file_path; | |
237 if (!browser_delegate->MapUrlToLocalFilePath( | |
238 GURL(request_list[i].resource_url), | |
239 true, // Use blocking API. | |
240 profile_directory, | |
241 &file_path)) { | |
242 continue; | |
243 } | |
244 | |
245 base::File file = OpenNaClReadExecImpl(file_path, true /* executable */); | |
246 if (!file.IsValid()) | |
247 continue; | |
248 | |
249 // Note: this runs only in Non-SFI mode. So, do not pass the file path; | |
250 // there's no validation caching in that case, so it's unnecessary. | |
251 // Moreover, it would expose the file path to the plugin. | |
252 result_list->push_back(NaClResourcePrefetchResult( | |
253 IPC::TakeFileHandleForProcess(file.Pass(), target_process), | |
254 base::FilePath(), | |
255 request_list[i].file_key)); | |
256 } | |
257 } | |
258 | |
259 base::File ReopenNexeFile( | |
260 base::File original_nexe_file, base::FilePath* nexe_file_path) { | |
261 // If no path is specified, use the original |nexe_file|. | |
262 if (!nexe_file_path || nexe_file_path->empty()) | |
263 return original_nexe_file.Pass(); | |
264 | |
265 // Reopen the nexe file. | |
266 base::File reopened_nexe_file = OpenNaClReadExecImpl( | |
267 *nexe_file_path, true /* executable */); | |
268 if (!reopened_nexe_file.IsValid()) { | |
269 // On fail, clear the path, which will eventually passed to the loader. | |
270 nexe_file_path->clear(); | |
271 return original_nexe_file.Pass(); | |
272 } | |
273 | |
274 // Note that, the |original_nexe_file| will be closed automatically. | |
275 return reopened_nexe_file.Pass(); | |
276 } | |
277 | |
278 // StartNaClExecution needs file operations. This function takes it, and | |
279 // should run on blocking pool. | |
280 base::File ResolveNaClFile( | |
281 base::FilePath* nexe_file_path, | |
282 base::File nexe_file, | |
283 const std::vector<NaClResourcePrefetchRequest>& | |
284 resource_prefetch_request_list, | |
285 const base::FilePath& profile_directory, | |
286 base::ProcessHandle target_process, | |
287 std::vector<NaClResourcePrefetchResult>* prefetched_resource_files) { | |
288 BatchOpenResourceFiles(resource_prefetch_request_list, | |
289 profile_directory, | |
290 target_process, | |
291 prefetched_resource_files); | |
292 return ReopenNexeFile(nexe_file.Pass(), nexe_file_path); | |
199 } | 293 } |
200 | 294 |
201 } // namespace | 295 } // namespace |
202 | 296 |
203 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = | 297 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = |
204 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds; | 298 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds; |
205 | 299 |
206 NaClProcessHost::NaClProcessHost( | 300 NaClProcessHost::NaClProcessHost( |
207 const GURL& manifest_url, | 301 const GURL& manifest_url, |
208 base::File nexe_file, | 302 base::File nexe_file, |
209 const NaClFileToken& nexe_token, | 303 const NaClFileToken& nexe_token, |
210 const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, | 304 const std::vector<NaClResourcePrefetchRequest>& |
305 resource_prefetch_request_list, | |
211 ppapi::PpapiPermissions permissions, | 306 ppapi::PpapiPermissions permissions, |
212 int render_view_id, | 307 int render_view_id, |
213 uint32 permission_bits, | 308 uint32 permission_bits, |
214 bool uses_nonsfi_mode, | 309 bool uses_nonsfi_mode, |
215 bool off_the_record, | 310 bool off_the_record, |
216 NaClAppProcessType process_type, | 311 NaClAppProcessType process_type, |
217 const base::FilePath& profile_directory) | 312 const base::FilePath& profile_directory) |
218 : manifest_url_(manifest_url), | 313 : manifest_url_(manifest_url), |
219 nexe_file_(nexe_file.Pass()), | 314 nexe_file_(nexe_file.Pass()), |
220 nexe_token_(nexe_token), | 315 nexe_token_(nexe_token), |
221 prefetched_resource_files_(prefetched_resource_files), | 316 resource_prefetch_request_list_(resource_prefetch_request_list), |
222 permissions_(permissions), | 317 permissions_(permissions), |
223 #if defined(OS_WIN) | 318 #if defined(OS_WIN) |
224 process_launched_by_broker_(false), | 319 process_launched_by_broker_(false), |
225 #endif | 320 #endif |
226 reply_msg_(NULL), | 321 reply_msg_(NULL), |
227 #if defined(OS_WIN) | 322 #if defined(OS_WIN) |
228 debug_exception_handler_requested_(false), | 323 debug_exception_handler_requested_(false), |
229 #endif | 324 #endif |
230 uses_nonsfi_mode_(uses_nonsfi_mode), | 325 uses_nonsfi_mode_(uses_nonsfi_mode), |
231 enable_debug_stub_(false), | 326 enable_debug_stub_(false), |
(...skipping 12 matching lines...) Expand all Loading... | |
244 // for this use case. | 339 // for this use case. |
245 process_->SetName(net::FormatUrl(manifest_url_, std::string())); | 340 process_->SetName(net::FormatUrl(manifest_url_, std::string())); |
246 | 341 |
247 enable_debug_stub_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 342 enable_debug_stub_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
248 switches::kEnableNaClDebug); | 343 switches::kEnableNaClDebug); |
249 DCHECK(process_type_ != kUnknownNaClProcessType); | 344 DCHECK(process_type_ != kUnknownNaClProcessType); |
250 enable_crash_throttling_ = process_type_ != kNativeNaClProcessType; | 345 enable_crash_throttling_ = process_type_ != kNativeNaClProcessType; |
251 } | 346 } |
252 | 347 |
253 NaClProcessHost::~NaClProcessHost() { | 348 NaClProcessHost::~NaClProcessHost() { |
349 PostCloseFile(nexe_file_.Pass()); | |
350 PostCloseFile(socket_for_renderer_.Pass()); | |
351 PostCloseFile(socket_for_sel_ldr_.Pass()); | |
352 | |
254 // Report exit status only if the process was successfully started. | 353 // Report exit status only if the process was successfully started. |
255 if (process_->GetData().handle != base::kNullProcessHandle) { | 354 if (process_->GetData().handle != base::kNullProcessHandle) { |
256 int exit_code = 0; | 355 int exit_code = 0; |
257 process_->GetTerminationStatus(false /* known_dead */, &exit_code); | 356 process_->GetTerminationStatus(false /* known_dead */, &exit_code); |
258 std::string message = | 357 std::string message = |
259 base::StringPrintf("NaCl process exited with status %i (0x%x)", | 358 base::StringPrintf("NaCl process exited with status %i (0x%x)", |
260 exit_code, exit_code); | 359 exit_code, exit_code); |
261 if (exit_code == 0) { | 360 if (exit_code == 0) { |
262 VLOG(1) << message; | 361 VLOG(1) << message; |
263 } else { | 362 } else { |
264 LOG(ERROR) << message; | 363 LOG(ERROR) << message; |
265 } | 364 } |
266 NaClBrowser::GetInstance()->OnProcessEnd(process_->GetData().id); | 365 NaClBrowser::GetInstance()->OnProcessEnd(process_->GetData().id); |
267 } | 366 } |
268 | 367 |
269 // Note: this does not work on Windows, though we currently support this | |
270 // prefetching feature only on Non-SFI mode, which is supported only on | |
271 // Linux/ChromeOS, so it should be ok. | |
272 #if defined(OS_WIN) | |
273 DCHECK(prefetched_resource_files_.empty()); | |
274 #else | |
275 for (size_t i = 0; i < prefetched_resource_files_.size(); ++i) { | |
276 // The process failed to launch for some reason. Close resource file | |
277 // handles. | |
278 base::File file(IPC::PlatformFileForTransitToFile( | |
279 prefetched_resource_files_[i].file)); | |
280 content::BrowserThread::GetBlockingPool()->PostTask( | |
281 FROM_HERE, | |
282 base::Bind(&CloseFile, base::Passed(file.Pass()))); | |
283 } | |
284 #endif | |
285 | |
286 if (reply_msg_) { | 368 if (reply_msg_) { |
287 // The process failed to launch for some reason. | 369 // The process failed to launch for some reason. |
288 // Don't keep the renderer hanging. | 370 // Don't keep the renderer hanging. |
289 reply_msg_->set_reply_error(); | 371 reply_msg_->set_reply_error(); |
290 nacl_host_message_filter_->Send(reply_msg_); | 372 nacl_host_message_filter_->Send(reply_msg_); |
291 } | 373 } |
292 #if defined(OS_WIN) | 374 #if defined(OS_WIN) |
293 if (process_launched_by_broker_) { | 375 if (process_launched_by_broker_) { |
294 NaClBrokerService::GetInstance()->OnLoaderDied(); | 376 NaClBrokerService::GetInstance()->OnLoaderDied(); |
295 } | 377 } |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
792 bool NaClProcessHost::StartNaClExecution() { | 874 bool NaClProcessHost::StartNaClExecution() { |
793 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 875 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
794 | 876 |
795 NaClStartParams params; | 877 NaClStartParams params; |
796 | 878 |
797 // Enable PPAPI proxy channel creation only for renderer processes. | 879 // Enable PPAPI proxy channel creation only for renderer processes. |
798 params.enable_ipc_proxy = enable_ppapi_proxy(); | 880 params.enable_ipc_proxy = enable_ppapi_proxy(); |
799 params.process_type = process_type_; | 881 params.process_type = process_type_; |
800 bool enable_nacl_debug = enable_debug_stub_ && | 882 bool enable_nacl_debug = enable_debug_stub_ && |
801 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); | 883 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); |
884 #if defined(OS_MACOSX) | |
885 base::ScopedFD memory_fd; | |
886 #endif // defined(OS_MACOSX) | |
887 #if defined(OS_POSIX) | |
888 base::ScopedFD debug_stub_server_bound_socket; | |
889 #endif // defined(OS_POSIX) | |
890 | |
802 if (uses_nonsfi_mode_) { | 891 if (uses_nonsfi_mode_) { |
803 // Currently, non-SFI mode is supported only on Linux. | 892 // Currently, non-SFI mode is supported only on Linux. |
804 #if defined(OS_LINUX) | 893 #if defined(OS_LINUX) |
805 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is | 894 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is |
806 // not created. | 895 // not created. |
807 DCHECK(!socket_for_sel_ldr_.IsValid()); | 896 DCHECK(!socket_for_sel_ldr_.IsValid()); |
808 #endif | 897 #endif |
809 if (enable_nacl_debug) { | 898 if (enable_nacl_debug) { |
810 base::ProcessId pid = base::GetProcId(process_->GetData().handle); | 899 base::ProcessId pid = base::GetProcId(process_->GetData().handle); |
811 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; | 900 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; |
812 } | 901 } |
813 } else { | 902 } else { |
814 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); | 903 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); |
815 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); | 904 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); |
816 params.version = NaClBrowser::GetDelegate()->GetVersionString(); | 905 params.version = NaClBrowser::GetDelegate()->GetVersionString(); |
817 params.enable_debug_stub = enable_nacl_debug; | 906 params.enable_debug_stub = enable_nacl_debug; |
818 | 907 |
819 const ChildProcessData& data = process_->GetData(); | 908 CHECK(nacl_browser->IrtFile().IsValid()); |
820 params.imc_bootstrap_handle = | |
821 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), data.handle); | |
822 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) { | |
823 return false; | |
824 } | |
825 | |
826 const base::File& irt_file = nacl_browser->IrtFile(); | |
827 CHECK(irt_file.IsValid()); | |
828 // Send over the IRT file handle. We don't close our own copy! | |
829 params.irt_handle = IPC::GetFileHandleForProcess( | |
830 irt_file.GetPlatformFile(), data.handle, false); | |
831 if (params.irt_handle == IPC::InvalidPlatformFileForTransit()) { | |
832 return false; | |
833 } | |
834 | 909 |
835 #if defined(OS_MACOSX) | 910 #if defined(OS_MACOSX) |
836 // For dynamic loading support, NaCl requires a file descriptor that | 911 // For dynamic loading support, NaCl requires a file descriptor that |
837 // was created in /tmp, since those created with shm_open() are not | 912 // was created in /tmp, since those created with shm_open() are not |
838 // mappable with PROT_EXEC. Rather than requiring an extra IPC | 913 // mappable with PROT_EXEC. Rather than requiring an extra IPC |
839 // round trip out of the sandbox, we create an FD here. | 914 // round trip out of the sandbox, we create an FD here. |
840 base::SharedMemory memory_buffer; | 915 base::SharedMemory memory_buffer; |
841 base::SharedMemoryCreateOptions options; | 916 base::SharedMemoryCreateOptions options; |
842 options.size = 1; | 917 options.size = 1; |
843 options.executable = true; | 918 options.executable = true; |
844 if (!memory_buffer.Create(options)) { | 919 if (!memory_buffer.Create(options)) { |
845 DLOG(ERROR) << "Failed to allocate memory buffer"; | 920 DLOG(ERROR) << "Failed to allocate memory buffer"; |
846 return false; | 921 return false; |
847 } | 922 } |
848 base::ScopedFD memory_fd(dup(memory_buffer.handle().fd)); | 923 memory_fd.reset(dup(memory_buffer.handle().fd)); |
849 if (!memory_fd.is_valid()) { | 924 if (!memory_fd.is_valid()) { |
850 DLOG(ERROR) << "Failed to dup() a file descriptor"; | 925 DLOG(ERROR) << "Failed to dup() a file descriptor"; |
851 return false; | 926 return false; |
852 } | 927 } |
853 params.mac_shm_fd = IPC::GetFileHandleForProcess( | |
854 memory_fd.release(), data.handle, true); | |
855 #endif | 928 #endif |
856 | 929 |
857 #if defined(OS_POSIX) | 930 #if defined(OS_POSIX) |
858 if (params.enable_debug_stub) { | 931 if (params.enable_debug_stub) |
859 net::SocketDescriptor server_bound_socket = GetDebugStubSocketHandle(); | 932 debug_stub_server_bound_socket.reset(GetDebugStubSocketHandle()); |
860 if (server_bound_socket != net::kInvalidSocket) { | |
861 params.debug_stub_server_bound_socket = IPC::GetFileHandleForProcess( | |
862 server_bound_socket, data.handle, true); | |
863 } | |
864 } | |
865 #endif | 933 #endif |
866 } | 934 } |
867 | 935 |
868 if (!crash_info_shmem_.ShareToProcess(process_->GetData().handle, | 936 // Transfer resources to |params|. |
869 ¶ms.crash_info_shmem_handle)) { | 937 // Hereafter, we should never return false, and should always send an IPC |
870 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; | 938 // to NaCl plugin process. Otherwise, the resources passed to |params| may |
871 return false; | 939 // be leaked. Note that these are resources for Plugin process, so we |
940 // cannot properly release those in this (browser) process. | |
941 { | |
942 const ChildProcessData& data = process_->GetData(); | |
943 if (!uses_nonsfi_mode_) { | |
944 params.imc_bootstrap_handle = IPC::TakeFileHandleForProcess( | |
945 socket_for_sel_ldr_.Pass(), data.handle); | |
946 // Send over the IRT file handle. We don't close our own copy! | |
947 params.irt_handle = IPC::GetFileHandleForProcess( | |
Mark Seaborn
2015/05/08 00:02:02
So you're changing the browser process to no longe
hidehiko
2015/05/11 16:52:49
My intention is "deferring the error handling to t
Mark Seaborn
2015/05/25 19:48:55
OK. If you want to say that the NaClProcessMsg_St
hidehiko
2015/05/26 14:32:59
Done.
| |
948 nacl_browser->IrtFile().GetPlatformFile(), data.handle, false); | |
949 | |
950 #if defined(OS_MACOSX) | |
951 params.mac_shm_fd = IPC::GetFileHandleForProcess( | |
952 memory_fd.release(), data.handle, true); | |
953 #endif | |
954 #if defined(OS_POSIX) | |
955 params.debug_stub_server_bound_socket = IPC::GetFileHandleForProcess( | |
956 debug_stub_server_bound_socket.release(), data.handle, true); | |
957 #endif | |
958 } | |
959 | |
960 if (!crash_info_shmem_.ShareToProcess(data.handle, | |
961 ¶ms.crash_info_shmem_handle)) { | |
962 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; | |
963 // Do not return here. | |
964 } | |
872 } | 965 } |
873 | 966 |
874 base::FilePath file_path; | 967 // We have to reopen the file in the browser process; we don't want a |
875 if (uses_nonsfi_mode_) { | 968 // compromised renderer to pass an arbitrary fd that could get loaded |
876 // Don't retrieve the file path when using nonsfi mode; there's no | 969 // into the plugin process. |
877 // validation caching in that case, so it's unnecessary work, and would | 970 // Don't retrieve the file path when using nonsfi mode; there's no |
878 // expose the file path to the plugin. | 971 // validation caching in that case, so it's unnecessary work, and would |
879 | 972 // expose the file path to the plugin. |
880 // Pass the pre-opened resource files to the loader. For the same reason | 973 scoped_ptr<base::FilePath> nexe_file_path; |
881 // as above, use an empty base::FilePath. | 974 if (!uses_nonsfi_mode_) { |
882 for (size_t i = 0; i < prefetched_resource_files_.size(); ++i) { | 975 nexe_file_path.reset(new base::FilePath); |
883 params.prefetched_resource_files.push_back(NaClResourcePrefetchResult( | 976 if (!NaClBrowser::GetInstance()->GetFilePath( |
884 prefetched_resource_files_[i].file, | 977 nexe_token_.lo, nexe_token_.hi, nexe_file_path.get())) { |
885 base::FilePath(), | 978 // Failed. Reset the pointer. |
886 prefetched_resource_files_[i].file_key)); | 979 nexe_file_path.reset(); |
887 } | 980 } |
888 prefetched_resource_files_.clear(); | |
889 } else { | |
890 if (NaClBrowser::GetInstance()->GetFilePath(nexe_token_.lo, | |
891 nexe_token_.hi, | |
892 &file_path)) { | |
893 // We have to reopen the file in the browser process; we don't want a | |
894 // compromised renderer to pass an arbitrary fd that could get loaded | |
895 // into the plugin process. | |
896 if (base::PostTaskAndReplyWithResult( | |
897 content::BrowserThread::GetBlockingPool(), | |
898 FROM_HERE, | |
899 base::Bind(OpenNaClReadExecImpl, | |
900 file_path, | |
901 true /* is_executable */), | |
902 base::Bind(&NaClProcessHost::StartNaClFileResolved, | |
903 weak_factory_.GetWeakPtr(), | |
904 params, | |
905 file_path))) { | |
906 return true; | |
907 } | |
908 } | |
909 // TODO(yusukes): Handle |prefetched_resource_files_| for SFI-NaCl. | |
910 DCHECK(prefetched_resource_files_.empty()); | |
911 } | 981 } |
912 | 982 |
913 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), | 983 // Pass the pre-opened resource files to the loader. |
914 process_->GetData().handle); | 984 scoped_ptr<std::vector<NaClResourcePrefetchResult> > |
915 process_->Send(new NaClProcessMsg_Start(params)); | 985 prefetched_resource_files; |
986 if (!resource_prefetch_request_list_.empty()) { | |
987 // TODO(yusukes): Handle |resource_prefetch_request_list_| for SFI-NaCl. | |
988 DCHECK(uses_nonsfi_mode_); | |
989 prefetched_resource_files.reset( | |
990 new std::vector<NaClResourcePrefetchResult>); | |
991 } | |
992 | |
993 // If file operation is necessary, run it on a blocking pool, where file | |
994 // operations are allowed. | |
995 if (nexe_file_path.get() || prefetched_resource_files.get()) { | |
996 if (base::PostTaskAndReplyWithResult( | |
997 content::BrowserThread::GetBlockingPool(), | |
998 FROM_HERE, | |
999 base::Bind(&ResolveNaClFile, | |
1000 nexe_file_path.get(), | |
1001 base::Passed(&nexe_file_), | |
1002 resource_prefetch_request_list_, | |
1003 profile_directory_, | |
1004 process_->GetData().handle, | |
1005 prefetched_resource_files.get()), | |
1006 base::Bind(&NaClProcessHost::StartNaClExecutionAfterFileResolved, | |
1007 weak_factory_.GetWeakPtr(), | |
1008 params, | |
1009 base::Passed(&nexe_file_path), | |
1010 base::Passed(&prefetched_resource_files)))) { | |
1011 return true; | |
1012 } | |
1013 } | |
1014 | |
1015 StartNaClExecutionAfterFileResolved( | |
1016 params, | |
1017 scoped_ptr<base::FilePath>(), | |
1018 scoped_ptr<std::vector<NaClResourcePrefetchResult> >(), | |
1019 nexe_file_.Pass()); | |
916 return true; | 1020 return true; |
917 } | 1021 } |
918 | 1022 |
919 void NaClProcessHost::StartNaClFileResolved( | 1023 void NaClProcessHost::StartNaClExecutionAfterFileResolved( |
920 NaClStartParams params, | 1024 NaClStartParams params, |
921 const base::FilePath& file_path, | 1025 scoped_ptr<base::FilePath> nexe_file_path, |
922 base::File checked_nexe_file) { | 1026 scoped_ptr<std::vector<NaClResourcePrefetchResult> > |
923 if (checked_nexe_file.IsValid()) { | 1027 prefetched_resource_files, |
924 // Release the file received from the renderer. This has to be done on a | 1028 base::File nexe_file) { |
925 // thread where IO is permitted, though. | 1029 // Pass the nexe file and its path to params. |
926 content::BrowserThread::GetBlockingPool()->PostTask( | 1030 params.nexe_file = IPC::TakeFileHandleForProcess( |
927 FROM_HERE, | 1031 nexe_file.Pass(), process_->GetData().handle); |
928 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); | 1032 if (nexe_file_path.get()) { |
929 params.nexe_file_path_metadata = file_path; | 1033 params.nexe_file_path_metadata = *nexe_file_path; |
930 params.nexe_file = IPC::TakeFileHandleForProcess( | |
931 checked_nexe_file.Pass(), process_->GetData().handle); | |
932 } else { | |
933 params.nexe_file = IPC::TakeFileHandleForProcess( | |
934 nexe_file_.Pass(), process_->GetData().handle); | |
935 } | 1034 } |
1035 | |
1036 // Pass prefetched resources to params. | |
1037 if (prefetched_resource_files.get()) { | |
1038 prefetched_resource_files->swap(params.prefetched_resource_files); | |
1039 } | |
1040 | |
936 process_->Send(new NaClProcessMsg_Start(params)); | 1041 process_->Send(new NaClProcessMsg_Start(params)); |
937 } | 1042 } |
938 | 1043 |
939 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is | 1044 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is |
940 // received. | 1045 // received. |
941 void NaClProcessHost::OnPpapiChannelsCreated( | 1046 void NaClProcessHost::OnPpapiChannelsCreated( |
942 const IPC::ChannelHandle& browser_channel_handle, | 1047 const IPC::ChannelHandle& browser_channel_handle, |
943 const IPC::ChannelHandle& ppapi_renderer_channel_handle, | 1048 const IPC::ChannelHandle& ppapi_renderer_channel_handle, |
944 const IPC::ChannelHandle& trusted_renderer_channel_handle, | 1049 const IPC::ChannelHandle& trusted_renderer_channel_handle, |
945 const IPC::ChannelHandle& manifest_service_channel_handle) { | 1050 const IPC::ChannelHandle& manifest_service_channel_handle) { |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1180 process.Pass(), info, | 1285 process.Pass(), info, |
1181 base::MessageLoopProxy::current(), | 1286 base::MessageLoopProxy::current(), |
1182 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1287 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
1183 weak_factory_.GetWeakPtr())); | 1288 weak_factory_.GetWeakPtr())); |
1184 return true; | 1289 return true; |
1185 } | 1290 } |
1186 } | 1291 } |
1187 #endif | 1292 #endif |
1188 | 1293 |
1189 } // namespace nacl | 1294 } // namespace nacl |
OLD | NEW |