CallOnceTest.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * Copyright 2016-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <deque>
  17. #include <mutex>
  18. #include <thread>
  19. #include <folly/portability/GTest.h>
  20. #include <folly/synchronization/CallOnce.h>
  21. static size_t const kNumThreads = 16;
  22. template <typename CallOnceFunc>
  23. void bm_impl(CallOnceFunc&& fn, size_t iters) {
  24. std::deque<std::thread> threads;
  25. for (size_t i = 0u; i < kNumThreads; ++i) {
  26. threads.emplace_back([&fn, iters] {
  27. for (size_t j = 0u; j < iters; ++j) {
  28. fn();
  29. }
  30. });
  31. }
  32. for (std::thread& t : threads) {
  33. t.join();
  34. }
  35. }
  36. TEST(FollyCallOnce, Simple) {
  37. folly::once_flag flag;
  38. auto fn = [&](int* outp) { ++*outp; };
  39. int out = 0;
  40. folly::call_once(flag, fn, &out);
  41. folly::call_once(flag, fn, &out);
  42. ASSERT_EQ(1, out);
  43. }
  44. TEST(FollyCallOnce, Exception) {
  45. struct ExpectedException {};
  46. folly::once_flag flag;
  47. size_t numCalls = 0;
  48. EXPECT_THROW(
  49. folly::call_once(
  50. flag,
  51. [&] {
  52. ++numCalls;
  53. throw ExpectedException();
  54. }),
  55. ExpectedException);
  56. EXPECT_EQ(1, numCalls);
  57. folly::call_once(flag, [&] { ++numCalls; });
  58. EXPECT_EQ(2, numCalls);
  59. }
  60. TEST(FollyCallOnce, Stress) {
  61. for (int i = 0; i < 100; ++i) {
  62. folly::once_flag flag;
  63. int out = 0;
  64. bm_impl([&] { folly::call_once(flag, [&] { ++out; }); }, 100);
  65. ASSERT_EQ(1, out);
  66. }
  67. }