barrier_closure_unittest.cc 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/barrier_closure.h"
  5. #include "base/bind.h"
  6. #include "base/callback.h"
  7. #include "base/callback_helpers.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/test/bind.h"
  10. #include "base/test/gtest_util.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. namespace {
  13. TEST(BarrierClosureTest, RunImmediatelyForZeroClosures) {
  14. int count = 0;
  15. base::RepeatingClosure barrier_closure = base::BarrierClosure(
  16. 0, base::BindLambdaForTesting([&count]() { ++count; }));
  17. EXPECT_EQ(1, count);
  18. }
  19. TEST(BarrierClosureTest, ChecksIfCalledForZeroClosures) {
  20. base::RepeatingClosure barrier_closure =
  21. base::BarrierClosure(0, base::DoNothing());
  22. EXPECT_FALSE(barrier_closure.is_null());
  23. EXPECT_CHECK_DEATH(barrier_closure.Run());
  24. }
  25. TEST(BarrierClosureTest, RunAfterNumClosures) {
  26. int count = 0;
  27. base::RepeatingClosure barrier_closure = base::BarrierClosure(
  28. 2, base::BindLambdaForTesting([&count]() { ++count; }));
  29. EXPECT_EQ(0, count);
  30. barrier_closure.Run();
  31. EXPECT_EQ(0, count);
  32. barrier_closure.Run();
  33. EXPECT_EQ(1, count);
  34. }
  35. class DestructionIndicator {
  36. public:
  37. // Sets |*destructed| to true in destructor.
  38. DestructionIndicator(bool* destructed) : destructed_(destructed) {
  39. *destructed_ = false;
  40. }
  41. ~DestructionIndicator() { *destructed_ = true; }
  42. void DoNothing() {}
  43. private:
  44. raw_ptr<bool> destructed_;
  45. };
  46. TEST(BarrierClosureTest, ReleasesDoneClosureWhenDone) {
  47. bool done_destructed = false;
  48. base::RepeatingClosure barrier_closure = base::BarrierClosure(
  49. 1,
  50. base::BindOnce(&DestructionIndicator::DoNothing,
  51. base::Owned(new DestructionIndicator(&done_destructed))));
  52. EXPECT_FALSE(done_destructed);
  53. barrier_closure.Run();
  54. EXPECT_TRUE(done_destructed);
  55. }
  56. // Tests a case when |done_closure| resets a |barrier_closure|.
  57. // |barrier_closure| is a RepeatingClosure holding the |done_closure|.
  58. // |done_closure| holds a pointer back to the |barrier_closure|. When
  59. // |barrier_closure| is Run() it calls ResetBarrierClosure() which erases the
  60. // |barrier_closure| while still inside of its Run(). The Run() implementation
  61. // (in base::BarrierClosure) must not try use itself after executing
  62. // ResetBarrierClosure() or this test would crash inside Run().
  63. TEST(BarrierClosureTest, KeepingClosureAliveUntilDone) {
  64. base::RepeatingClosure barrier_closure;
  65. barrier_closure =
  66. base::BarrierClosure(1, base::BindLambdaForTesting([&barrier_closure]() {
  67. barrier_closure = base::RepeatingClosure();
  68. }));
  69. barrier_closure.Run();
  70. EXPECT_TRUE(barrier_closure.is_null());
  71. }
  72. } // namespace