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

Side by Side Diff: base/process_util_posix.cc

Issue 13845008: [Mac] Remove base::LaunchSynchronize and rewrite content::MachBroker. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix link_settings Created 7 years, 8 months 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 | Annotate | Revision Log
« no previous file with comments | « base/process_util.h ('k') | content/app/content_main_runner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <dirent.h> 5 #include <dirent.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <signal.h> 8 #include <signal.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <sys/resource.h> 10 #include <sys/resource.h>
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 } 597 }
598 598
599 bool LaunchProcess(const std::vector<std::string>& argv, 599 bool LaunchProcess(const std::vector<std::string>& argv,
600 const LaunchOptions& options, 600 const LaunchOptions& options,
601 ProcessHandle* process_handle) { 601 ProcessHandle* process_handle) {
602 size_t fd_shuffle_size = 0; 602 size_t fd_shuffle_size = 0;
603 if (options.fds_to_remap) { 603 if (options.fds_to_remap) {
604 fd_shuffle_size = options.fds_to_remap->size(); 604 fd_shuffle_size = options.fds_to_remap->size();
605 } 605 }
606 606
607 #if defined(OS_MACOSX)
608 if (options.synchronize) {
609 // When synchronizing, the "read" end of the synchronization pipe needs
610 // to make it to the child process. This is handled by mapping it back to
611 // itself.
612 ++fd_shuffle_size;
613 }
614 #endif // defined(OS_MACOSX)
615
616 InjectiveMultimap fd_shuffle1; 607 InjectiveMultimap fd_shuffle1;
617 InjectiveMultimap fd_shuffle2; 608 InjectiveMultimap fd_shuffle2;
618 fd_shuffle1.reserve(fd_shuffle_size); 609 fd_shuffle1.reserve(fd_shuffle_size);
619 fd_shuffle2.reserve(fd_shuffle_size); 610 fd_shuffle2.reserve(fd_shuffle_size);
620 611
621 scoped_ptr<char*[]> argv_cstr(new char*[argv.size() + 1]); 612 scoped_ptr<char*[]> argv_cstr(new char*[argv.size() + 1]);
622 scoped_ptr<char*[]> new_environ; 613 scoped_ptr<char*[]> new_environ;
623 if (options.environ) 614 if (options.environ)
624 new_environ.reset(AlterEnvironment(*options.environ, GetEnvironment())); 615 new_environ.reset(AlterEnvironment(*options.environ, GetEnvironment()));
625 616
626 #if defined(OS_MACOSX)
627 int synchronization_pipe_fds[2];
628 file_util::ScopedFD synchronization_read_fd;
629 file_util::ScopedFD synchronization_write_fd;
630
631 if (options.synchronize) {
632 // wait means "don't return from LaunchProcess until the child exits", and
633 // synchronize means "return from LaunchProcess but don't let the child
634 // run until LaunchSynchronize is called". These two options are highly
635 // incompatible.
636 DCHECK(!options.wait);
637
638 // Create the pipe used for synchronization.
639 if (HANDLE_EINTR(pipe(synchronization_pipe_fds)) != 0) {
640 DPLOG(ERROR) << "pipe";
641 return false;
642 }
643
644 // The parent process will only use synchronization_write_fd as the write
645 // side of the pipe. It can close the read side as soon as the child
646 // process has forked off. The child process will only use
647 // synchronization_read_fd as the read side of the pipe. In that process,
648 // the write side can be closed as soon as it has forked.
649 synchronization_read_fd.reset(&synchronization_pipe_fds[0]);
650 synchronization_write_fd.reset(&synchronization_pipe_fds[1]);
651 }
652 #endif // OS_MACOSX
653
654 pid_t pid; 617 pid_t pid;
655 #if defined(OS_LINUX) 618 #if defined(OS_LINUX)
656 if (options.clone_flags) { 619 if (options.clone_flags) {
657 pid = syscall(__NR_clone, options.clone_flags, 0, 0, 0); 620 pid = syscall(__NR_clone, options.clone_flags, 0, 0, 0);
658 } else 621 } else
659 #endif 622 #endif
660 { 623 {
661 pid = fork(); 624 pid = fork();
662 } 625 }
663 626
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 #if defined(OS_MACOSX) 699 #if defined(OS_MACOSX)
737 RestoreDefaultExceptionHandler(); 700 RestoreDefaultExceptionHandler();
738 #endif // defined(OS_MACOSX) 701 #endif // defined(OS_MACOSX)
739 702
740 ResetChildSignalHandlersToDefaults(); 703 ResetChildSignalHandlersToDefaults();
741 704
742 if (options.debug) { 705 if (options.debug) {
743 RAW_LOG(INFO, "Right after signal/exception handler restoration."); 706 RAW_LOG(INFO, "Right after signal/exception handler restoration.");
744 } 707 }
745 708
746 #if defined(OS_MACOSX)
747 if (options.synchronize) {
748 // The "write" side of the synchronization pipe belongs to the parent.
749 synchronization_write_fd.reset(); // closes synchronization_pipe_fds[1]
750 }
751 #endif // defined(OS_MACOSX)
752
753 #if 0 709 #if 0
754 // When debugging it can be helpful to check that we really aren't making 710 // When debugging it can be helpful to check that we really aren't making
755 // any hidden calls to malloc. 711 // any hidden calls to malloc.
756 void *malloc_thunk = 712 void *malloc_thunk =
757 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095); 713 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095);
758 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); 714 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
759 memset(reinterpret_cast<void*>(malloc), 0xff, 8); 715 memset(reinterpret_cast<void*>(malloc), 0xff, 8);
760 #endif // 0 716 #endif // 0
761 717
762 // DANGER: no calls to malloc are allowed from now on: 718 // DANGER: no calls to malloc are allowed from now on:
(...skipping 19 matching lines...) Expand all
782 it != options.fds_to_remap->end(); ++it) { 738 it != options.fds_to_remap->end(); ++it) {
783 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false)); 739 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false));
784 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false)); 740 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false));
785 } 741 }
786 } 742 }
787 743
788 if (options.debug) { 744 if (options.debug) {
789 RAW_LOG(INFO, "Right after fd_shuffle push_backs."); 745 RAW_LOG(INFO, "Right after fd_shuffle push_backs.");
790 } 746 }
791 747
792 #if defined(OS_MACOSX)
793 if (options.synchronize) {
794 // Remap the read side of the synchronization pipe back onto itself,
795 // ensuring that it won't be closed by CloseSuperfluousFds.
796 int keep_fd = *synchronization_read_fd.get();
797 fd_shuffle1.push_back(InjectionArc(keep_fd, keep_fd, false));
798 fd_shuffle2.push_back(InjectionArc(keep_fd, keep_fd, false));
799 }
800 #endif // defined(OS_MACOSX)
801
802 if (options.environ) 748 if (options.environ)
803 SetEnvironment(new_environ.get()); 749 SetEnvironment(new_environ.get());
804 750
805 // fd_shuffle1 is mutated by this call because it cannot malloc. 751 // fd_shuffle1 is mutated by this call because it cannot malloc.
806 if (!ShuffleFileDescriptors(&fd_shuffle1)) 752 if (!ShuffleFileDescriptors(&fd_shuffle1))
807 _exit(127); 753 _exit(127);
808 754
809 if (options.debug) { 755 if (options.debug) {
810 RAW_LOG(INFO, "Right after ShuffleFileDescriptors"); 756 RAW_LOG(INFO, "Right after ShuffleFileDescriptors");
811 } 757 }
812 758
813 CloseSuperfluousFds(fd_shuffle2); 759 CloseSuperfluousFds(fd_shuffle2);
814 760
815 if (options.debug) { 761 if (options.debug) {
816 RAW_LOG(INFO, "Right after CloseSuperfluousFds"); 762 RAW_LOG(INFO, "Right after CloseSuperfluousFds");
817 } 763 }
818 764
819 #if defined(OS_MACOSX)
820 if (options.synchronize) {
821 // Do a blocking read to wait until the parent says it's OK to proceed.
822 // The byte that's read here is written by LaunchSynchronize.
823 char read_char;
824 int read_result =
825 HANDLE_EINTR(read(*synchronization_read_fd.get(), &read_char, 1));
826 if (read_result != 1) {
827 RAW_LOG(ERROR, "LaunchProcess: synchronization read: error");
828 _exit(127);
829 }
830
831 // The pipe is no longer useful. Don't let it live on in the new process
832 // after exec.
833 synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0]
834 }
835 #endif // defined(OS_MACOSX)
836
837 if (options.debug) { 765 if (options.debug) {
838 RAW_LOG(INFO, "Right before execvp"); 766 RAW_LOG(INFO, "Right before execvp");
839 } 767 }
840 768
841 for (size_t i = 0; i < argv.size(); i++) 769 for (size_t i = 0; i < argv.size(); i++)
842 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 770 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
843 argv_cstr[argv.size()] = NULL; 771 argv_cstr[argv.size()] = NULL;
844 execvp(argv_cstr[0], argv_cstr.get()); 772 execvp(argv_cstr[0], argv_cstr.get());
845 773
846 RAW_LOG(ERROR, "LaunchProcess: failed to execvp:"); 774 RAW_LOG(ERROR, "LaunchProcess: failed to execvp:");
847 RAW_LOG(ERROR, argv_cstr[0]); 775 RAW_LOG(ERROR, argv_cstr[0]);
848 _exit(127); 776 _exit(127);
849 } else { 777 } else {
850 // Parent process 778 // Parent process
851 if (options.wait) { 779 if (options.wait) {
852 // While this isn't strictly disk IO, waiting for another process to 780 // While this isn't strictly disk IO, waiting for another process to
853 // finish is the sort of thing ThreadRestrictions is trying to prevent. 781 // finish is the sort of thing ThreadRestrictions is trying to prevent.
854 base::ThreadRestrictions::AssertIOAllowed(); 782 base::ThreadRestrictions::AssertIOAllowed();
855 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0)); 783 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0));
856 DPCHECK(ret > 0); 784 DPCHECK(ret > 0);
857 } 785 }
858 786
859 if (process_handle) 787 if (process_handle)
860 *process_handle = pid; 788 *process_handle = pid;
861
862 #if defined(OS_MACOSX)
863 if (options.synchronize) {
864 // The "read" side of the synchronization pipe belongs to the child.
865 synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0]
866 *options.synchronize = new int(*synchronization_write_fd.release());
867 }
868 #endif // defined(OS_MACOSX)
869 } 789 }
870 790
871 return true; 791 return true;
872 } 792 }
873 793
874 794
875 bool LaunchProcess(const CommandLine& cmdline, 795 bool LaunchProcess(const CommandLine& cmdline,
876 const LaunchOptions& options, 796 const LaunchOptions& options,
877 ProcessHandle* process_handle) { 797 ProcessHandle* process_handle) {
878 return LaunchProcess(cmdline.argv(), options, process_handle); 798 return LaunchProcess(cmdline.argv(), options, process_handle);
879 } 799 }
880 800
881 #if defined(OS_MACOSX)
882 void LaunchSynchronize(LaunchSynchronizationHandle handle) {
883 int synchronization_fd = *handle;
884 file_util::ScopedFD synchronization_fd_closer(&synchronization_fd);
885 delete handle;
886
887 // Write a '\0' character to the pipe.
888 if (HANDLE_EINTR(write(synchronization_fd, "", 1)) != 1) {
889 DPLOG(ERROR) << "write";
890 }
891 }
892 #endif // defined(OS_MACOSX)
893
894 ProcessMetrics::~ProcessMetrics() { } 801 ProcessMetrics::~ProcessMetrics() { }
895 802
896 void RaiseProcessToHighPriority() { 803 void RaiseProcessToHighPriority() {
897 // On POSIX, we don't actually do anything here. We could try to nice() or 804 // On POSIX, we don't actually do anything here. We could try to nice() or
898 // setpriority() or sched_getscheduler, but these all require extra rights. 805 // setpriority() or sched_getscheduler, but these all require extra rights.
899 } 806 }
900 807
901 TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) { 808 TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
902 return GetTerminationStatusImpl(handle, false /* can_block */, exit_code); 809 return GetTerminationStatusImpl(handle, false /* can_block */, exit_code);
903 } 810 }
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
1372 if (IsChildDead(process)) 1279 if (IsChildDead(process))
1373 return; 1280 return;
1374 1281
1375 BackgroundReaper* reaper = new BackgroundReaper(process, 0); 1282 BackgroundReaper* reaper = new BackgroundReaper(process, 0);
1376 PlatformThread::CreateNonJoinable(0, reaper); 1283 PlatformThread::CreateNonJoinable(0, reaper);
1377 } 1284 }
1378 1285
1379 #endif // !defined(OS_MACOSX) 1286 #endif // !defined(OS_MACOSX)
1380 1287
1381 } // namespace base 1288 } // namespace base
OLDNEW
« no previous file with comments | « base/process_util.h ('k') | content/app/content_main_runner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698