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

Unified Diff: sandbox/linux/services/thread_helpers.cc

Issue 1310773006: Update sandbox/linux from upstream (Closed) Base URL: ssh://ssh.github.com/domokit/mojo.git@master
Patch Set: Update to 3909ebfa69566f7374a6900e63cd4d3c73a35378 Created 5 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sandbox/linux/services/thread_helpers.h ('k') | sandbox/linux/services/thread_helpers_unittests.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/linux/services/thread_helpers.cc
diff --git a/sandbox/linux/services/thread_helpers.cc b/sandbox/linux/services/thread_helpers.cc
index 80766a9bc5dc970666efbb5c3e7ff21ad646c4ff..c1ba04a248c37c75346690dfdfaa5297dbd5c713 100644
--- a/sandbox/linux/services/thread_helpers.cc
+++ b/sandbox/linux/services/thread_helpers.cc
@@ -29,6 +29,10 @@ namespace {
const char kAssertSingleThreadedError[] =
"Current process is not mono-threaded!";
+const char kAssertThreadDoesNotAppearInProcFS[] =
+ "Started thread does not appear in /proc";
+const char kAssertThreadDoesNotDisappearInProcFS[] =
+ "Stopped thread does not disappear in /proc";
bool IsSingleThreadedImpl(int proc_fd) {
CHECK_LE(0, proc_fd);
@@ -56,13 +60,18 @@ bool IsThreadPresentInProcFS(int proc_fd,
return true;
}
+bool IsNotThreadPresentInProcFS(int proc_fd,
+ const std::string& thread_id_dir_str) {
+ return !IsThreadPresentInProcFS(proc_fd, thread_id_dir_str);
+}
+
// Run |cb| in a loop until it returns false. Every time |cb| runs, sleep
// for an exponentially increasing amount of time. |cb| is expected to return
// false very quickly and this will crash if it doesn't happen within ~64ms on
// Debug builds (2s on Release builds).
// This is guaranteed to not sleep more than twice as much as the bare minimum
// amount of time.
-void RunWhileTrue(const base::Callback<bool(void)>& cb) {
+void RunWhileTrue(const base::Callback<bool(void)>& cb, const char* message) {
#if defined(NDEBUG)
// In Release mode, crash after 30 iterations, which means having spent
// roughly 2s in
@@ -91,8 +100,7 @@ void RunWhileTrue(const base::Callback<bool(void)>& cb) {
PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts)));
}
- LOG(FATAL) << kAssertSingleThreadedError << " (iterations: " << kMaxIterations
- << ")";
+ LOG(FATAL) << message << " (iterations: " << kMaxIterations << ")";
NOTREACHED();
}
@@ -101,6 +109,51 @@ bool IsMultiThreaded(int proc_fd) {
return !ThreadHelpers::IsSingleThreaded(proc_fd);
}
+enum class ThreadAction { Start, Stop };
+
+bool ChangeThreadStateAndWatchProcFS(
+ int proc_fd, base::Thread* thread, ThreadAction action) {
+ DCHECK_LE(0, proc_fd);
+ DCHECK(thread);
+ DCHECK(action == ThreadAction::Start || action == ThreadAction::Stop);
+
+ base::Callback<bool(void)> cb;
+ const char* message;
+
+ if (action == ThreadAction::Start) {
+ // Should start the thread before calling thread_id().
+ if (!thread->Start())
+ return false;
+ }
+
+ const base::PlatformThreadId thread_id = thread->thread_id();
+ const std::string thread_id_dir_str =
+ "self/task/" + base::IntToString(thread_id) + "/";
+
+ if (action == ThreadAction::Stop) {
+ // The target thread should exist in /proc.
+ DCHECK(IsThreadPresentInProcFS(proc_fd, thread_id_dir_str));
+ thread->Stop();
+ }
+
+ // The kernel is at liberty to wake the thread id futex before updating
+ // /proc. Start() above or following Stop(), the thread is started or joined,
+ // but entries in /proc may not have been updated.
+ if (action == ThreadAction::Start) {
+ cb = base::Bind(&IsNotThreadPresentInProcFS, proc_fd, thread_id_dir_str);
+ message = kAssertThreadDoesNotAppearInProcFS;
+ } else {
+ cb = base::Bind(&IsThreadPresentInProcFS, proc_fd, thread_id_dir_str);
+ message = kAssertThreadDoesNotDisappearInProcFS;
+ }
+ RunWhileTrue(cb, message);
+
+ DCHECK_EQ(action == ThreadAction::Start,
+ IsThreadPresentInProcFS(proc_fd, thread_id_dir_str));
+
+ return true;
+}
+
} // namespace
// static
@@ -119,7 +172,7 @@ bool ThreadHelpers::IsSingleThreaded() {
void ThreadHelpers::AssertSingleThreaded(int proc_fd) {
DCHECK_LE(0, proc_fd);
const base::Callback<bool(void)> cb = base::Bind(&IsMultiThreaded, proc_fd);
- RunWhileTrue(cb);
+ RunWhileTrue(cb, kAssertSingleThreadedError);
}
void ThreadHelpers::AssertSingleThreaded() {
@@ -128,25 +181,15 @@ void ThreadHelpers::AssertSingleThreaded() {
}
// static
+bool ThreadHelpers::StartThreadAndWatchProcFS(int proc_fd,
+ base::Thread* thread) {
+ return ChangeThreadStateAndWatchProcFS(proc_fd, thread, ThreadAction::Start);
+}
+
+// static
bool ThreadHelpers::StopThreadAndWatchProcFS(int proc_fd,
base::Thread* thread) {
- DCHECK_LE(0, proc_fd);
- DCHECK(thread);
- const base::PlatformThreadId thread_id = thread->thread_id();
- const std::string thread_id_dir_str =
- "self/task/" + base::IntToString(thread_id) + "/";
-
- // The kernel is at liberty to wake the thread id futex before updating
- // /proc. Following Stop(), the thread is joined, but entries in /proc may
- // not have been updated.
- thread->Stop();
-
- const base::Callback<bool(void)> cb =
- base::Bind(&IsThreadPresentInProcFS, proc_fd, thread_id_dir_str);
-
- RunWhileTrue(cb);
-
- return true;
+ return ChangeThreadStateAndWatchProcFS(proc_fd, thread, ThreadAction::Stop);
}
// static
« no previous file with comments | « sandbox/linux/services/thread_helpers.h ('k') | sandbox/linux/services/thread_helpers_unittests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698