Index: base/message_loop_unittest.cc |
diff --git a/base/message_loop_unittest.cc b/base/message_loop_unittest.cc |
index 44d545f15f842fab9d47151206c034551515d18a..0fa35f36d3be6c37f9ab693dfb7c5c53388514e2 100644 |
--- a/base/message_loop_unittest.cc |
+++ b/base/message_loop_unittest.cc |
@@ -2,10 +2,12 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "base/eintr_wrapper.h" |
#include "base/logging.h" |
#include "base/message_loop.h" |
#include "base/platform_thread.h" |
#include "base/ref_counted.h" |
+#include "base/task.h" |
#include "base/thread.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -1455,6 +1457,70 @@ TEST(MessageLoopTest, NonNestableDelayedInNestedLoop) { |
RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, true); |
} |
+class DummyTask : public Task { |
+ public: |
+ DummyTask(int num_tasks) : num_tasks_(num_tasks) {} |
+ |
+ virtual void Run() { |
+ if (num_tasks_ > 1) { |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ new DummyTask(num_tasks_ - 1)); |
+ } else { |
+ MessageLoop::current()->Quit(); |
+ } |
+ } |
+ |
+ private: |
+ const int num_tasks_; |
+}; |
+ |
+class DummyTaskObserver : public MessageLoop::TaskObserver { |
+ public: |
+ DummyTaskObserver(int num_tasks) |
+ : num_tasks_started_(0), |
+ num_tasks_processed_(0), |
+ num_tasks_(num_tasks) {} |
+ |
+ virtual ~DummyTaskObserver() {} |
+ |
+ virtual void WillProcessTask(base::TimeTicks /* birth_time */) { |
+ num_tasks_started_++; |
+ EXPECT_LE(num_tasks_started_, num_tasks_); |
+ EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1); |
+ } |
+ |
+ virtual void DidProcessTask() { |
+ num_tasks_processed_++; |
+ EXPECT_LE(num_tasks_started_, num_tasks_); |
+ EXPECT_EQ(num_tasks_started_, num_tasks_processed_); |
+ } |
+ |
+ int num_tasks_started() const { return num_tasks_started_; } |
+ int num_tasks_processed() const { return num_tasks_processed_; } |
+ |
+ private: |
+ int num_tasks_started_; |
+ int num_tasks_processed_; |
+ const int num_tasks_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DummyTaskObserver); |
+}; |
+ |
+TEST(MessageLoopTest, TaskObserver) { |
+ const int kNumTasks = 6; |
+ DummyTaskObserver observer(kNumTasks); |
+ |
+ MessageLoop loop; |
+ loop.AddTaskObserver(&observer); |
+ loop.PostTask(FROM_HERE, new DummyTask(kNumTasks)); |
+ loop.Run(); |
+ loop.RemoveTaskObserver(&observer); |
+ |
+ EXPECT_EQ(kNumTasks, observer.num_tasks_started()); |
+ EXPECT_EQ(kNumTasks, observer.num_tasks_processed()); |
+} |
+ |
#if defined(OS_WIN) |
TEST(MessageLoopTest, Dispatcher) { |
// This test requires a UI loop |
@@ -1479,8 +1545,7 @@ TEST(MessageLoopTest, WaitForIO) { |
namespace { |
-class QuitDelegate : public |
- base::MessagePumpLibevent::Watcher { |
+class QuitDelegate : public base::MessagePumpLibevent::Watcher { |
public: |
virtual void OnFileCanWriteWithoutBlocking(int fd) { |
MessageLoop::current()->Quit(); |
@@ -1490,8 +1555,6 @@ class QuitDelegate : public |
} |
}; |
-} // namespace |
- |
TEST(MessageLoopTest, FileDescriptorWatcherOutlivesMessageLoop) { |
// Simulate a MessageLoop that dies before an FileDescriptorWatcher. |
// This could happen when people use the Singleton pattern or atexit. |
@@ -1517,8 +1580,8 @@ TEST(MessageLoopTest, FileDescriptorWatcherOutlivesMessageLoop) { |
// and don't run the message loop, just destroy it. |
} |
} |
- close(pipefds[0]); |
- close(pipefds[1]); |
+ HANDLE_EINTR(close(pipefds[0])); |
+ HANDLE_EINTR(close(pipefds[1])); |
} |
TEST(MessageLoopTest, FileDescriptorWatcherDoubleStop) { |
@@ -1540,8 +1603,10 @@ TEST(MessageLoopTest, FileDescriptorWatcherDoubleStop) { |
controller.StopWatchingFileDescriptor(); |
} |
} |
- close(pipefds[0]); |
- close(pipefds[1]); |
+ HANDLE_EINTR(close(pipefds[0])); |
+ HANDLE_EINTR(close(pipefds[1])); |
} |
+} // namespace |
+ |
#endif // defined(OS_POSIX) |