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

Side by Side Diff: base/zygote_manager.cc

Issue 119289: Enable zygote manager by default. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 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/zygote_manager.h ('k') | chrome/test/chrome_process_util.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) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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 "base/zygote_manager.h" 5 #include "base/zygote_manager.h"
6 6
7 #if defined(OS_LINUX) 7 #if defined(OS_LINUX)
8 8
9 #include <errno.h> 9 #include <errno.h>
10 #include <fcntl.h> 10 #include <fcntl.h>
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 } 47 }
48 if (lockfd_ != -1) { 48 if (lockfd_ != -1) {
49 close(lockfd_); 49 close(lockfd_);
50 lockfd_ = -1; 50 lockfd_ = -1;
51 } 51 }
52 if (canary_fd_ != -1) { 52 if (canary_fd_ != -1) {
53 // Wake up the poll() in ReadAndHandleMessage() 53 // Wake up the poll() in ReadAndHandleMessage()
54 close(canary_fd_); 54 close(canary_fd_);
55 canary_fd_ = -1; 55 canary_fd_ = -1;
56 } 56 }
57 #ifndef OFFICIAL_BUILD
58 // Closing the canary kills the server,
59 // so after this it's ok for e.g. unit tests
60 // to start a new zygote server.
61 (void) unsetenv("ZYGOTE_MANAGER_STARTED");
62 #endif
57 } 63 }
58 64
59 // Runs in client process 65 // Runs in client process
60 ZygoteManager* ZygoteManager::Get() { 66 ZygoteManager* ZygoteManager::Get() {
61 static bool checked = false; 67 static bool checked = false;
62 static bool enabled = false; 68 static bool enabled = false;
63 if (!checked) { 69 if (!checked) {
64 enabled = (getenv("ENABLE_ZYGOTE_MANAGER") != NULL); 70 enabled = (getenv("DISABLE_ZYGOTE_MANAGER") == NULL);
65 // sanity check - make sure all the places that relaunch chrome
66 // have been zygotified.
67 if (enabled)
68 DCHECK(getenv("ZYGOTE_MANAGER_STARTED") == NULL)
69 << "fork/exec used instead of LongFork";
70 (void) setenv("ZYGOTE_MANAGER_STARTED", "1", 1);
71 checked = true; 71 checked = true;
72 } 72 }
73 if (!enabled) 73 if (!enabled)
74 return NULL; 74 return NULL;
75 return Singleton<ZygoteManager>::get(); 75 return Singleton<ZygoteManager>::get();
76 } 76 }
77 77
78 // Runs in zygote manager process 78 // Runs in zygote manager process
79 int ZygoteManager::UnpickleHeader(const Pickle& reply, void** iter) { 79 int ZygoteManager::UnpickleHeader(const Pickle& reply, void** iter) {
80 std::string magic; 80 std::string magic;
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 // Wait at most one minute. This lets us detect case where 587 // Wait at most one minute. This lets us detect case where
588 // canary socket is closed abruptly because the main client aborted. 588 // canary socket is closed abruptly because the main client aborted.
589 // Also lets us reap dead children once a minute even if we don't get SIGCHLD. 589 // Also lets us reap dead children once a minute even if we don't get SIGCHLD.
590 // We'd like to wait less time, but that's hard on battery life. 590 // We'd like to wait less time, but that's hard on battery life.
591 // Note: handle EINTR manually here, not with wrapper, as we need 591 // Note: handle EINTR manually here, not with wrapper, as we need
592 // to return when we're interrupted so caller can reap promptly. 592 // to return when we're interrupted so caller can reap promptly.
593 int nactive = poll(watcher, 2, 60*1000); 593 int nactive = poll(watcher, 2, 60*1000);
594 594
595 if (nactive == -1) { 595 if (nactive == -1) {
596 if (errno == EINTR) { 596 if (errno == EINTR) {
597 LOG(INFO) << "poll interrupted";
598 // Probably SIGCHLD. Return to main loop so it can reap. 597 // Probably SIGCHLD. Return to main loop so it can reap.
599 return true; 598 return true;
600 } 599 }
601 LOG(ERROR) << "poll failed, errno " << errno << ", aborting"; 600 LOG(ERROR) << "poll failed, errno " << errno << ", aborting";
602 return false; 601 return false;
603 } 602 }
604 603
605 // If it was the canary, exit 604 // If it was the canary, exit
606 if (watcher[0].revents != 0) { 605 if (watcher[0].revents != 0) {
607 LOG(INFO) << "notified of peer destruction, exiting"; 606 LOG(INFO) << "notified of peer destruction, exiting";
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 return true; 715 return true;
717 } 716 }
718 717
719 // Called only by ChromeMain(), forks the zygote manager process. 718 // Called only by ChromeMain(), forks the zygote manager process.
720 std::vector<std::string>* ZygoteManager::Start() { 719 std::vector<std::string>* ZygoteManager::Start() {
721 DCHECK(lockfd_ == -1); 720 DCHECK(lockfd_ == -1);
722 DCHECK(canary_fd_ == -1); 721 DCHECK(canary_fd_ == -1);
723 DCHECK(server_fd_ == -1); 722 DCHECK(server_fd_ == -1);
724 DCHECK(client_fd_ == -1); 723 DCHECK(client_fd_ == -1);
725 724
725 #ifndef OFFICIAL_BUILD
726 // Disallow nested ZygoteManager servers
727 CHECK(getenv("ZYGOTE_MANAGER_STARTED") == NULL) << "already started?!";
728 (void) setenv("ZYGOTE_MANAGER_STARTED", "1", 1);
729 #endif
730
726 int pipe_fds[2]; 731 int pipe_fds[2];
727 732
728 // Avoid using the reserved fd slots. 733 // Avoid using the reserved fd slots.
729 int reserved_fds[kReservedFds]; 734 int reserved_fds[kReservedFds];
730 for (int i=0; i < kReservedFds; i++) 735 for (int i=0; i < kReservedFds; i++)
731 reserved_fds[i] = open("/dev/null", O_RDONLY, 0); 736 reserved_fds[i] = open("/dev/null", O_RDONLY, 0);
732 737
733 // Create the main communications pipe. 738 // Create the main communications pipe.
734 int err = HANDLE_EINTR(socketpair(AF_UNIX, SOCK_DGRAM, 0, pipe_fds)); 739 int err = HANDLE_EINTR(socketpair(AF_UNIX, SOCK_DGRAM, 0, pipe_fds));
735 if (err != 0) { 740 if (err != 0) {
(...skipping 18 matching lines...) Expand all
754 lockfd_ = mkstemp(lockfile); 759 lockfd_ = mkstemp(lockfile);
755 if (lockfd_ == -1) { 760 if (lockfd_ == -1) {
756 // TODO(dkegel): real error handling 761 // TODO(dkegel): real error handling
757 exit(99); 762 exit(99);
758 } 763 }
759 lockfile_.assign(lockfile); 764 lockfile_.assign(lockfile);
760 765
761 // Fork a fork server. 766 // Fork a fork server.
762 pid_t childpid = fork(); 767 pid_t childpid = fork();
763 768
764 if (childpid) { 769 if (!childpid) {
765 for (int i=0; i < kReservedFds; i++) 770 for (int i=0; i < kReservedFds; i++)
766 close(reserved_fds[i]); 771 close(reserved_fds[i]);
767 772
768 // Original parent. Continues on with the main program 773 // Original child. Continues on with the main program
769 // and becomes the first client. 774 // and becomes the first client.
770 close(server_fd_); 775 close(server_fd_);
771 server_fd_ = -1; 776 server_fd_ = -1;
772 777
773 close(pipe_fds[1]); 778 close(pipe_fds[1]);
774 canary_fd_ = pipe_fds[0]; 779 canary_fd_ = pipe_fds[0];
775 780
776 // Return now to indicate this is the original process. 781 // Return now to indicate this is the original process.
777 return NULL; 782 return NULL;
778 } else { 783 } else {
779 close(lockfd_); 784 close(lockfd_);
780 785
781 close(pipe_fds[0]); 786 close(pipe_fds[0]);
782 canary_fd_ = pipe_fds[1]; 787 canary_fd_ = pipe_fds[1];
783 788
784 // We need to accept SIGCHLD, even though our handler is a no-op because 789 // We need to accept SIGCHLD, even though our handler is a no-op because
785 // otherwise we cannot wait on children. (According to POSIX 2001.) 790 // otherwise we cannot wait on children. (According to POSIX 2001.)
786 // (And otherwise poll() might not wake up on SIGCHLD.) 791 // (And otherwise poll() might not wake up on SIGCHLD.)
787 struct sigaction action; 792 struct sigaction action;
788 memset(&action, 0, sizeof(action)); 793 memset(&action, 0, sizeof(action));
789 action.sa_handler = SIGCHLDHandler; 794 action.sa_handler = SIGCHLDHandler;
790 CHECK(sigaction(SIGCHLD, &action, NULL) == 0); 795 CHECK(sigaction(SIGCHLD, &action, NULL) == 0);
791 796
792 // Original child. Acts as the server. 797 // Original process. Acts as the server.
793 while (true) { 798 while (true) {
794 std::vector<std::string>* newargv = NULL; 799 std::vector<std::string>* newargv = NULL;
795 if (!ReadAndHandleMessage(&newargv)) 800 if (!ReadAndHandleMessage(&newargv))
796 break; 801 break;
797 if (newargv) { 802 if (newargv) {
798 // Return new commandline to show caller this is a new child process. 803 // Return new commandline to show caller this is a new child process.
799 return newargv; 804 return newargv;
800 } 805 }
801 // Server process continues around loop. 806 // Server process continues around loop.
802 807
803 // Reap children. 808 // Reap children.
804 while (true) { 809 while (true) {
805 int status = -1; 810 int status = -1;
806 pid_t reaped = waitpid(-1, &status, WNOHANG); 811 pid_t reaped = waitpid(-1, &status, WNOHANG);
807 if (reaped != -1 && reaped != 0) { 812 if (reaped != -1 && reaped != 0) {
808 LOG(INFO) << "Reaped pid " << reaped; 813 LOG(INFO) << "Reaped pid " << reaped;
809 continue; 814 continue;
810 } 815 }
811 break; 816 break;
812 } 817 }
813 } 818 }
814 // Server cleanup after EOF or error reading from the socket. 819 // Server cleanup after EOF or error reading from the socket.
815 // Chrome doesn't seem to get here in practice.
816 Delete(FilePath(lockfile_), false); 820 Delete(FilePath(lockfile_), false);
817 // TODO(dkegel): real error handling 821 // TODO(dkegel): real error handling
818 LOG(INFO) << "exiting. " << cached_fds_.size() << " cached fds."; 822 LOG(INFO) << "exiting. " << cached_fds_.size() << " cached fds.";
819 std::map<std::string, int>::iterator i; 823 std::map<std::string, int>::iterator i;
820 for (i = cached_fds_.begin(); i != cached_fds_.end(); ++i) { 824 for (i = cached_fds_.begin(); i != cached_fds_.end(); ++i) {
821 LOG(INFO) << "Closing fd " << i->second << " filename " << i->first; 825 LOG(INFO) << "Closing fd " << i->second << " filename " << i->first;
822 close(i->second); 826 close(i->second);
823 } 827 }
824 exit(-1); 828 exit(0);
825 } 829 }
826 } 830 }
827 } 831 }
828 #endif // defined(OS_LINUX) 832 #endif // defined(OS_LINUX)
OLDNEW
« no previous file with comments | « base/zygote_manager.h ('k') | chrome/test/chrome_process_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698