Chromium Code Reviews| Index: base/process/launch_posix.cc |
| diff --git a/base/process/launch_posix.cc b/base/process/launch_posix.cc |
| index 3708af6bac417b49e4015fed93eb49966ed78363..593678af53f6aa95393c06392c39730a6c5ef3dd 100644 |
| --- a/base/process/launch_posix.cc |
| +++ b/base/process/launch_posix.cc |
| @@ -77,6 +77,29 @@ void SetEnvironment(char** env) { |
| #endif |
| } |
| +// Set the calling thread's signal mask to *new_set, and set *old_set |
| +// to the previous signal mask. Returns true if successful. |
| +bool SetSignalMask(const sigset_t *new_set, sigset_t *old_set) { |
| + int error; |
| +#if defined(OS_ANDROID) |
| + // POSIX says pthread_sigmask() must be used in multi-threaded processes, |
| + // but Android's pthread_sigmask() was broken until 4.1: |
| + // https://code.google.com/p/android/issues/detail?id=15337 |
| + // http://stackoverflow.com/questions/13777109/pthread-sigmask-on-android-not-working |
| + error = sigprocmask(SIG_SETMASK, new_set, old_set); |
| +#else |
| + error = pthread_sigmask(SIG_SETMASK, new_set, old_set); |
| + if (error != 0) { |
| + errno = error; |
| + } |
| +#endif |
| + if (error != 0) { |
| + DPLOG(ERROR) << "SetSignalMask failed"; |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| #if !defined(OS_LINUX) || \ |
| (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) |
| void ResetChildSignalHandlersToDefaults() { |
| @@ -394,9 +417,17 @@ bool LaunchProcess(const std::vector<std::string>& argv, |
| if (options.environ) |
| new_environ.reset(AlterEnvironment(*options.environ, GetEnvironment())); |
| + sigset_t full_sigset; |
| + sigfillset(&full_sigset); |
| + sigset_t old_sigset; |
| + if (!SetSignalMask(&full_sigset, &old_sigset)) { |
| + return false; |
| + } |
| + |
| pid_t pid; |
| #if defined(OS_LINUX) |
| if (options.clone_flags) { |
| + CHECK_EQ(0, options.clone_flags & (CLONE_THREAD | CLONE_VM)); |
|
jln (very slow on Chromium)
2013/08/02 05:28:47
RAW_CHECK
mdempsky_google
2013/08/02 18:45:00
Done.
|
| pid = syscall(__NR_clone, options.clone_flags, 0, 0, 0); |
| } else |
| #endif |
| @@ -404,6 +435,12 @@ bool LaunchProcess(const std::vector<std::string>& argv, |
| pid = fork(); |
| } |
|
jln (very slow on Chromium)
2013/08/02 05:28:47
// Always restore the signal mask in the parent.
mdempsky_google
2013/08/02 18:45:00
Done.
|
| + if (pid != 0) { |
| + if (!SetSignalMask(&old_sigset, NULL)) { |
| + NOTREACHED(); |
|
jln (very slow on Chromium)
2013/08/02 05:28:47
RAW_CHECK
mdempsky_google
2013/08/02 16:12:51
Is RAW_CHECK(x) guaranteed to always evaluate x?
mdempsky_google
2013/08/02 18:45:00
I moved the RAW_CHECK()s directly into SetSignalMa
|
| + } |
| + } |
| + |
| if (pid < 0) { |
| DPLOG(ERROR) << "fork"; |
| return false; |
| @@ -469,6 +506,9 @@ bool LaunchProcess(const std::vector<std::string>& argv, |
| #endif // defined(OS_MACOSX) |
| ResetChildSignalHandlersToDefaults(); |
| + if (!SetSignalMask(&old_sigset, NULL)) { |
| + NOTREACHED(); |
|
jln (very slow on Chromium)
2013/08/02 05:28:47
RAW_CHECK
|
| + } |
| #if 0 |
| // When debugging it can be helpful to check that we really aren't making |
|
jln (very slow on Chromium)
2013/08/02 05:28:47
I guess this was intended right after the fork() b
|