summaryrefslogtreecommitdiff
path: root/chromium/base/sequenced_task_runner_unittest.cc
blob: b999ffc8cd811d03eb61e9907750d8234328e466 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/sequenced_task_runner.h"

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace {

struct DeleteCounter {
  DeleteCounter(int* counter, scoped_refptr<SequencedTaskRunner> task_runner)
      : counter_(counter),
        task_runner_(std::move(task_runner)) {
  }
  ~DeleteCounter() {
    ++*counter_;
    EXPECT_TRUE(!task_runner_ || task_runner_->RunsTasksOnCurrentThread());
  }

  int* counter_;
  scoped_refptr<SequencedTaskRunner> task_runner_;
};

}  // namespace

TEST(SequencedTaskRunnerTest, OnTaskRunnerDeleter) {
  base::MessageLoop message_loop;
  base::Thread thread("Foreign");
  thread.Start();

  scoped_refptr<SequencedTaskRunner> current_thread =
      message_loop.task_runner();
  scoped_refptr<SequencedTaskRunner> foreign_thread =
      thread.task_runner();

  using SequenceBoundUniquePtr =
      std::unique_ptr<DeleteCounter, OnTaskRunnerDeleter>;

  int counter = 0;
  SequenceBoundUniquePtr ptr(new DeleteCounter(&counter, current_thread),
                             OnTaskRunnerDeleter(current_thread));
  EXPECT_EQ(0, counter);
  foreign_thread->PostTask(
      FROM_HERE,
      Bind([](SequenceBoundUniquePtr) {},
           Passed(&ptr)));

  {
    RunLoop run_loop;
    foreign_thread->PostTaskAndReply(
        FROM_HERE,
        Bind([]{}),
        run_loop.QuitClosure());
    run_loop.Run();
  }
  EXPECT_EQ(1, counter);

  DeleteCounter* raw = new DeleteCounter(&counter, nullptr);
  SequenceBoundUniquePtr ptr2(raw, OnTaskRunnerDeleter(foreign_thread));
  EXPECT_EQ(1, counter);

  thread.Stop();
  ptr2 = nullptr;
  ASSERT_EQ(1, counter);

  delete raw;
  EXPECT_EQ(2, counter);
}

}  // namespace base