summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authordkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-08 23:29:11 +0000
committerdkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-08 23:29:11 +0000
commit78c6dd65953307dd0b550a16d92267a450c01309 (patch)
tree41fbb424f0285933d7fddd1d06d24b0b3a1a349b /base
parent37cd3a96b55aac1dad9016c05e78b5983972f985 (diff)
downloadchromium_src-78c6dd65953307dd0b550a16d92267a450c01309.zip
chromium_src-78c6dd65953307dd0b550a16d92267a450c01309.tar.gz
chromium_src-78c6dd65953307dd0b550a16d92267a450c01309.tar.bz2
Enable zygote manager by default.
Fix broken recursion check. Make OpenFile warning less scary, indicate it's normal at start of ui tests. Make ui tests pass. Avoid generating extra code on Mac. BUG=11841 TEST=start the browser, then make chrome and all .pak files unreadable; or alternately, start an installed browser, and uninstall the browser while it's running. Then create a new tab and browse to two new sites. Review URL: http://codereview.chromium.org/119289 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17909 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/file_util_posix.cc2
-rw-r--r--base/logging.cc6
-rw-r--r--base/process_util.h9
-rw-r--r--base/process_util_linux.cc46
-rw-r--r--base/process_util_unittest.cc7
-rw-r--r--base/zygote_manager.cc30
-rw-r--r--base/zygote_manager.h4
7 files changed, 86 insertions, 18 deletions
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index b9aa206..7f40c17 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -633,7 +633,7 @@ bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) {
file_ = zm->OpenFile(file_name.value().c_str());
if (file_ == -1) {
LOG(INFO) << "Zygote manager can't open " << file_name.value()
- << ", retrying locally";
+ << ", retrying locally. (OK at start of ui_tests.)";
}
}
#endif // defined(OS_LINUX)
diff --git a/base/logging.cc b/base/logging.cc
index b6aa730..77e9583 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -208,7 +208,7 @@ bool InitializeLogFileHandle() {
}
}
SetFilePointer(log_file, 0, 0, FILE_END);
-#elif defined(OS_POSIX)
+#elif defined(OS_LINUX)
// Reserve global fd slots.
int reserved_fds[kReservedFds];
for (int i=0; i < kReservedFds; i++)
@@ -222,6 +222,10 @@ bool InitializeLogFileHandle() {
if (log_file == NULL)
return false;
+#elif defined(OS_POSIX)
+ log_file = fopen(log_file_name->c_str(), "a");
+ if (log_file == NULL)
+ return false;
#endif
}
diff --git a/base/process_util.h b/base/process_util.h
index b558541..4fe081f 100644
--- a/base/process_util.h
+++ b/base/process_util.h
@@ -23,6 +23,7 @@
#include <vector>
#include "base/command_line.h"
+#include "base/file_path.h"
#include "base/process.h"
#if defined(OS_WIN)
@@ -87,6 +88,14 @@ void CloseProcessHandle(ProcessHandle process);
// Win XP SP1 as well.
ProcessId GetProcId(ProcessHandle process);
+#if defined(OS_LINUX)
+// Returns the ID for the parent of the given process.
+ProcessId GetParentProcessId(ProcessHandle process);
+
+// Returns the path to the executable of the given process.
+FilePath GetProcessExecutablePath(ProcessHandle process);
+#endif
+
#if defined(OS_POSIX)
// Sets all file descriptors to close on exec except for stdin, stdout
// and stderr.
diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc
index 78725cc..ba2d8cd 100644
--- a/base/process_util_linux.cc
+++ b/base/process_util_linux.cc
@@ -7,10 +7,10 @@
#include <ctype.h>
#include <dirent.h>
#include <fcntl.h>
-#include <unistd.h>
#include <string>
#include <sys/types.h>
#include <sys/wait.h>
+#include <unistd.h>
#include "base/eintr_wrapper.h"
#include "base/file_util.h"
@@ -42,6 +42,50 @@ void GetProcStats(pid_t pid, std::vector<std::string>* proc_stats) {
namespace base {
+ProcessId GetParentProcessId(ProcessHandle process) {
+ FilePath stat_file("/proc");
+ stat_file = stat_file.Append(IntToString(process));
+ stat_file = stat_file.Append("status");
+ std::string status;
+ if (!file_util::ReadFileToString(stat_file, &status))
+ return -1;
+
+ StringTokenizer tokenizer(status, ":\n");
+ ParsingState state = KEY_NAME;
+ std::string last_key_name;
+ while (tokenizer.GetNext()) {
+ switch (state) {
+ case KEY_NAME:
+ last_key_name = tokenizer.token();
+ state = KEY_VALUE;
+ break;
+ case KEY_VALUE:
+ DCHECK(!last_key_name.empty());
+ if (last_key_name == "PPid") {
+ pid_t ppid = StringToInt(tokenizer.token());
+ return ppid;
+ }
+ state = KEY_NAME;
+ break;
+ }
+ }
+ NOTREACHED();
+ return -1;
+}
+
+FilePath GetProcessExecutablePath(ProcessHandle process) {
+ FilePath stat_file("/proc");
+ stat_file = stat_file.Append(IntToString(process));
+ stat_file = stat_file.Append("exe");
+ char exename[2048];
+ ssize_t len = readlink(stat_file.value().c_str(), exename, sizeof(exename));
+ if (len < 1) {
+ // No such process. Happens frequently in e.g. TerminateAllChromeProcesses
+ return FilePath();
+ }
+ return FilePath(std::string(exename, len));
+}
+
bool ForkApp(const std::vector<std::string>& argv,
const file_handle_mapping_vector& fds_to_remap,
ProcessHandle* process_handle) {
diff --git a/base/process_util_unittest.cc b/base/process_util_unittest.cc
index 1e5c272..7b30be6 100644
--- a/base/process_util_unittest.cc
+++ b/base/process_util_unittest.cc
@@ -270,6 +270,13 @@ TEST_F(ProcessUtilTest, GetAppOutput) {
EXPECT_STREQ("foobar42", output.c_str());
}
+#if defined(OS_LINUX)
+TEST_F(ProcessUtilTest, GetParentProcessId) {
+ base::ProcessId ppid = GetParentProcessId(GetCurrentProcId());
+ EXPECT_EQ(ppid, getppid());
+}
+#endif
+
#endif // defined(OS_POSIX)
} // namespace base
diff --git a/base/zygote_manager.cc b/base/zygote_manager.cc
index 2310c2d..7f0043a 100644
--- a/base/zygote_manager.cc
+++ b/base/zygote_manager.cc
@@ -54,6 +54,12 @@ ZygoteManager::~ZygoteManager() {
close(canary_fd_);
canary_fd_ = -1;
}
+#ifndef OFFICIAL_BUILD
+ // Closing the canary kills the server,
+ // so after this it's ok for e.g. unit tests
+ // to start a new zygote server.
+ (void) unsetenv("ZYGOTE_MANAGER_STARTED");
+#endif
}
// Runs in client process
@@ -61,13 +67,7 @@ ZygoteManager* ZygoteManager::Get() {
static bool checked = false;
static bool enabled = false;
if (!checked) {
- enabled = (getenv("ENABLE_ZYGOTE_MANAGER") != NULL);
- // sanity check - make sure all the places that relaunch chrome
- // have been zygotified.
- if (enabled)
- DCHECK(getenv("ZYGOTE_MANAGER_STARTED") == NULL)
- << "fork/exec used instead of LongFork";
- (void) setenv("ZYGOTE_MANAGER_STARTED", "1", 1);
+ enabled = (getenv("DISABLE_ZYGOTE_MANAGER") == NULL);
checked = true;
}
if (!enabled)
@@ -594,7 +594,6 @@ bool ZygoteManager::ReadAndHandleMessage(std::vector<std::string>** newargv) {
if (nactive == -1) {
if (errno == EINTR) {
- LOG(INFO) << "poll interrupted";
// Probably SIGCHLD. Return to main loop so it can reap.
return true;
}
@@ -723,6 +722,12 @@ std::vector<std::string>* ZygoteManager::Start() {
DCHECK(server_fd_ == -1);
DCHECK(client_fd_ == -1);
+#ifndef OFFICIAL_BUILD
+ // Disallow nested ZygoteManager servers
+ CHECK(getenv("ZYGOTE_MANAGER_STARTED") == NULL) << "already started?!";
+ (void) setenv("ZYGOTE_MANAGER_STARTED", "1", 1);
+#endif
+
int pipe_fds[2];
// Avoid using the reserved fd slots.
@@ -761,11 +766,11 @@ std::vector<std::string>* ZygoteManager::Start() {
// Fork a fork server.
pid_t childpid = fork();
- if (childpid) {
+ if (!childpid) {
for (int i=0; i < kReservedFds; i++)
close(reserved_fds[i]);
- // Original parent. Continues on with the main program
+ // Original child. Continues on with the main program
// and becomes the first client.
close(server_fd_);
server_fd_ = -1;
@@ -789,7 +794,7 @@ std::vector<std::string>* ZygoteManager::Start() {
action.sa_handler = SIGCHLDHandler;
CHECK(sigaction(SIGCHLD, &action, NULL) == 0);
- // Original child. Acts as the server.
+ // Original process. Acts as the server.
while (true) {
std::vector<std::string>* newargv = NULL;
if (!ReadAndHandleMessage(&newargv))
@@ -812,7 +817,6 @@ std::vector<std::string>* ZygoteManager::Start() {
}
}
// Server cleanup after EOF or error reading from the socket.
- // Chrome doesn't seem to get here in practice.
Delete(FilePath(lockfile_), false);
// TODO(dkegel): real error handling
LOG(INFO) << "exiting. " << cached_fds_.size() << " cached fds.";
@@ -821,7 +825,7 @@ std::vector<std::string>* ZygoteManager::Start() {
LOG(INFO) << "Closing fd " << i->second << " filename " << i->first;
close(i->second);
}
- exit(-1);
+ exit(0);
}
}
}
diff --git a/base/zygote_manager.h b/base/zygote_manager.h
index 7936167..5b94533 100644
--- a/base/zygote_manager.h
+++ b/base/zygote_manager.h
@@ -29,8 +29,8 @@ class ZygoteManager {
// The normal way to get a ZygoteManager is via this singleton factory.
static ZygoteManager* Get();
- ZygoteManager() : server_fd_(-1), client_fd_(-1), canary_fd_(-1),
- lockfd_(-1) {
+ ZygoteManager() :
+ server_fd_(-1), client_fd_(-1), canary_fd_(-1), lockfd_(-1) {
}
~ZygoteManager();