AtForkTest.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright 2017-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 <folly/detail/AtFork.h>
  17. #include <folly/portability/GTest.h>
  18. #include <glog/logging.h>
  19. #include <atomic>
  20. #include <mutex>
  21. #include <thread>
  22. TEST(ThreadLocal, AtFork) {
  23. int foo;
  24. bool forked = false;
  25. folly::detail::AtFork::registerHandler(
  26. &foo,
  27. [&] {
  28. forked = true;
  29. return true;
  30. },
  31. [] {},
  32. [] {});
  33. auto pid = fork();
  34. if (pid) {
  35. int status;
  36. auto pid2 = wait(&status);
  37. EXPECT_EQ(status, 0);
  38. EXPECT_EQ(pid, pid2);
  39. } else {
  40. exit(0);
  41. }
  42. EXPECT_TRUE(forked);
  43. forked = false;
  44. folly::detail::AtFork::unregisterHandler(&foo);
  45. pid = fork();
  46. if (pid) {
  47. int status;
  48. auto pid2 = wait(&status);
  49. EXPECT_EQ(status, 0);
  50. EXPECT_EQ(pid, pid2);
  51. } else {
  52. exit(0);
  53. }
  54. EXPECT_FALSE(forked);
  55. }
  56. TEST(ThreadLocal, AtForkOrdering) {
  57. std::atomic<bool> done{false};
  58. std::atomic<bool> started{false};
  59. std::mutex a;
  60. std::mutex b;
  61. int foo;
  62. int foo2;
  63. folly::detail::AtFork::registerHandler(
  64. &foo,
  65. [&] { return a.try_lock(); },
  66. [&] { a.unlock(); },
  67. [&] { a.unlock(); });
  68. folly::detail::AtFork::registerHandler(
  69. &foo2,
  70. [&] { return b.try_lock(); },
  71. [&] { b.unlock(); },
  72. [&] { b.unlock(); });
  73. auto thr = std::thread([&]() {
  74. std::lock_guard<std::mutex> g(a);
  75. started = true;
  76. usleep(100);
  77. std::lock_guard<std::mutex> g2(b);
  78. });
  79. while (!started) {
  80. }
  81. auto pid = fork();
  82. if (pid) {
  83. int status;
  84. auto pid2 = wait(&status);
  85. EXPECT_EQ(status, 0);
  86. EXPECT_EQ(pid, pid2);
  87. } else {
  88. exit(0);
  89. }
  90. done = true;
  91. thr.join();
  92. }