Moved the calls to the MessageLoop destruction observers to after the pending tasks are deleted.
BUG=None
TEST=Unit-test provided, tests should pass and all hell should not break loose.
Review URL: http://codereview.chromium.org/5318003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67623 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/base/message_loop_unittest.cc b/base/message_loop_unittest.cc
index a3c3307..537c606 100644
--- a/base/message_loop_unittest.cc
+++ b/base/message_loop_unittest.cc
@@ -1647,3 +1647,67 @@
} // namespace
#endif // defined(OS_POSIX)
+
+namespace {
+class RunAtDestructionTask : public Task {
+ public:
+ RunAtDestructionTask(bool* task_destroyed, bool* destruction_observer_called)
+ : task_destroyed_(task_destroyed),
+ destruction_observer_called_(destruction_observer_called) {
+ }
+ ~RunAtDestructionTask() {
+ EXPECT_FALSE(*destruction_observer_called_);
+ *task_destroyed_ = true;
+ }
+ virtual void Run() {
+ // This task should never run.
+ ADD_FAILURE();
+ }
+ private:
+ bool* task_destroyed_;
+ bool* destruction_observer_called_;
+};
+
+class MLDestructionObserver : public MessageLoop::DestructionObserver {
+ public:
+ MLDestructionObserver(bool* task_destroyed, bool* destruction_observer_called)
+ : task_destroyed_(task_destroyed),
+ destruction_observer_called_(destruction_observer_called),
+ task_destroyed_before_message_loop_(false) {
+ }
+ virtual void WillDestroyCurrentMessageLoop() {
+ task_destroyed_before_message_loop_ = *task_destroyed_;
+ *destruction_observer_called_ = true;
+ }
+ bool task_destroyed_before_message_loop() const {
+ return task_destroyed_before_message_loop_;
+ }
+ private:
+ bool* task_destroyed_;
+ bool* destruction_observer_called_;
+ bool task_destroyed_before_message_loop_;
+};
+
+} // namespace
+
+TEST(MessageLoopTest, DestructionObserverTest) {
+ // Verify that the destruction observer gets called at the very end (after
+ // all the pending tasks have been destroyed).
+ MessageLoop* loop = new MessageLoop;
+ const int kDelayMS = 100;
+
+ bool task_destroyed = false;
+ bool destruction_observer_called = false;
+
+ MLDestructionObserver observer(&task_destroyed, &destruction_observer_called);
+ loop->AddDestructionObserver(&observer);
+ loop->PostDelayedTask(
+ FROM_HERE,
+ new RunAtDestructionTask(&task_destroyed, &destruction_observer_called),
+ kDelayMS);
+ delete loop;
+ EXPECT_TRUE(observer.task_destroyed_before_message_loop());
+ // The task should have been destroyed when we deleted the loop.
+ EXPECT_TRUE(task_destroyed);
+ EXPECT_TRUE(destruction_observer_called);
+}