pr33582_fork_handler.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. --- a/src/core/lib/event_engine/forkable.cc (index)
  2. +++ a/src/core/lib/event_engine/forkable.cc (working tree)
  3. @@ -15,6 +15,7 @@
  4. #include <grpc/support/port_platform.h>
  5. #include "src/core/lib/event_engine/forkable.h"
  6. +#include "src/core/lib/gprpp/fork.h"
  7. #ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
  8. @@ -35,6 +36,11 @@ bool g_registered Y_ABSL_GUARDED_BY(g_mu){false};
  9. // This must be ordered because there are ordering dependencies between
  10. // certain fork handlers.
  11. grpc_core::NoDestruct<std::vector<Forkable*>> g_forkables Y_ABSL_GUARDED_BY(g_mu);
  12. +
  13. +bool IsForkEnabled() {
  14. + return grpc_core::Fork::Enabled();
  15. +}
  16. +
  17. } // namespace
  18. Forkable::Forkable() { ManageForkable(this); }
  19. @@ -42,23 +48,31 @@ Forkable::Forkable() { ManageForkable(this); }
  20. Forkable::~Forkable() { StopManagingForkable(this); }
  21. void RegisterForkHandlers() {
  22. - grpc_core::MutexLock lock(g_mu.get());
  23. - if (!std::exchange(g_registered, true)) {
  24. - pthread_atfork(PrepareFork, PostforkParent, PostforkChild);
  25. + if (IsForkEnabled()) {
  26. + grpc_core::MutexLock lock(g_mu.get());
  27. + if (!std::exchange(g_registered, true)) {
  28. +#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
  29. + pthread_atfork(PrepareFork, PostforkParent, PostforkChild);
  30. +#endif
  31. + }
  32. }
  33. };
  34. void PrepareFork() {
  35. - grpc_core::MutexLock lock(g_mu.get());
  36. - for (auto forkable_iter = g_forkables->rbegin();
  37. - forkable_iter != g_forkables->rend(); ++forkable_iter) {
  38. - (*forkable_iter)->PrepareFork();
  39. + if (IsForkEnabled()) {
  40. + grpc_core::MutexLock lock(g_mu.get());
  41. + for (auto forkable_iter = g_forkables->rbegin();
  42. + forkable_iter != g_forkables->rend(); ++forkable_iter) {
  43. + (*forkable_iter)->PrepareFork();
  44. + }
  45. }
  46. }
  47. void PostforkParent() {
  48. - grpc_core::MutexLock lock(g_mu.get());
  49. - for (auto* forkable : *g_forkables) {
  50. - forkable->PostforkParent();
  51. + if (IsForkEnabled()) {
  52. + grpc_core::MutexLock lock(g_mu.get());
  53. + for (auto* forkable : *g_forkables) {
  54. + forkable->PostforkParent();
  55. + }
  56. }
  57. }
  58. @@ -69,30 +83,36 @@ void SetSkipPostForkChild() {
  59. }
  60. void PostforkChild() {
  61. - y_absl::ResetDeadlockGraphMu();
  62. - if (skip_postfork_child) {
  63. - return;
  64. - }
  65. - grpc_core::MutexLock lock(g_mu.get());
  66. - for (auto* forkable : *g_forkables) {
  67. - forkable->PostforkChild();
  68. + if (IsForkEnabled()) {
  69. + y_absl::ResetDeadlockGraphMu();
  70. + if (skip_postfork_child) {
  71. + return;
  72. + }
  73. + grpc_core::MutexLock lock(g_mu.get());
  74. + for (auto* forkable : *g_forkables) {
  75. + forkable->PostforkChild();
  76. + }
  77. }
  78. }
  79. void ManageForkable(Forkable* forkable) {
  80. - grpc_core::MutexLock lock(g_mu.get());
  81. - g_forkables->push_back(forkable);
  82. + if (IsForkEnabled()) {
  83. + grpc_core::MutexLock lock(g_mu.get());
  84. + g_forkables->push_back(forkable);
  85. + }
  86. }
  87. void StopManagingForkable(Forkable* forkable) {
  88. - grpc_core::MutexLock lock(g_mu.get());
  89. - auto iter = std::find(g_forkables->begin(), g_forkables->end(), forkable);
  90. - // We've faced with the issue that destructor for TimerManager object is called
  91. - // between PrepareFork and PostforkParent.
  92. - // In result in PostforkParent we try to access not valid object via forkable ptr.
  93. - // https://github.com/grpc/grpc/issues/33516
  94. - if (iter != g_forkables->end()) {
  95. - g_forkables->erase(iter);
  96. + if (IsForkEnabled()) {
  97. + grpc_core::MutexLock lock(g_mu.get());
  98. + auto iter = std::find(g_forkables->begin(), g_forkables->end(), forkable);
  99. + // We've faced with the issue that destructor for TimerManager object is called
  100. + // between PrepareFork and PostforkParent.
  101. + // In result in PostforkParent we try to access not valid object via forkable ptr.
  102. + // https://github.com/grpc/grpc/issues/33516
  103. + if (iter != g_forkables->end()) {
  104. + g_forkables->erase(iter);
  105. + }
  106. }
  107. }