|
|
|
@ -22,15 +22,17 @@ |
|
|
|
|
|
|
|
|
|
#include "absl/container/flat_hash_set.h" |
|
|
|
|
|
|
|
|
|
#include "src/core/lib/gprpp/no_destruct.h" |
|
|
|
|
#include "src/core/lib/gprpp/sync.h" |
|
|
|
|
|
|
|
|
|
namespace grpc_event_engine { |
|
|
|
|
namespace experimental { |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
grpc_core::Mutex g_mu; |
|
|
|
|
bool g_registered{false}; |
|
|
|
|
absl::flat_hash_set<Forkable*> g_forkables; |
|
|
|
|
grpc_core::NoDestruct<grpc_core::Mutex> g_mu; |
|
|
|
|
bool g_registered ABSL_GUARDED_BY(g_mu){false}; |
|
|
|
|
grpc_core::NoDestruct<absl::flat_hash_set<Forkable*>> g_forkables |
|
|
|
|
ABSL_GUARDED_BY(g_mu); |
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
Forkable::Forkable() { ManageForkable(this); } |
|
|
|
@ -38,39 +40,39 @@ Forkable::Forkable() { ManageForkable(this); } |
|
|
|
|
Forkable::~Forkable() { StopManagingForkable(this); } |
|
|
|
|
|
|
|
|
|
void RegisterForkHandlers() { |
|
|
|
|
grpc_core::MutexLock lock(&g_mu); |
|
|
|
|
grpc_core::MutexLock lock(g_mu.get()); |
|
|
|
|
GPR_ASSERT(!absl::exchange(g_registered, true)); |
|
|
|
|
pthread_atfork(PrepareFork, PostforkParent, PostforkChild); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
void PrepareFork() { |
|
|
|
|
grpc_core::MutexLock lock(&g_mu); |
|
|
|
|
for (auto* forkable : g_forkables) { |
|
|
|
|
grpc_core::MutexLock lock(g_mu.get()); |
|
|
|
|
for (auto* forkable : *g_forkables) { |
|
|
|
|
forkable->PrepareFork(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
void PostforkParent() { |
|
|
|
|
grpc_core::MutexLock lock(&g_mu); |
|
|
|
|
for (auto* forkable : g_forkables) { |
|
|
|
|
grpc_core::MutexLock lock(g_mu.get()); |
|
|
|
|
for (auto* forkable : *g_forkables) { |
|
|
|
|
forkable->PostforkParent(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void PostforkChild() { |
|
|
|
|
grpc_core::MutexLock lock(&g_mu); |
|
|
|
|
for (auto* forkable : g_forkables) { |
|
|
|
|
grpc_core::MutexLock lock(g_mu.get()); |
|
|
|
|
for (auto* forkable : *g_forkables) { |
|
|
|
|
forkable->PostforkChild(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ManageForkable(Forkable* forkable) { |
|
|
|
|
grpc_core::MutexLock lock(&g_mu); |
|
|
|
|
g_forkables.insert(forkable); |
|
|
|
|
grpc_core::MutexLock lock(g_mu.get()); |
|
|
|
|
g_forkables->insert(forkable); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void StopManagingForkable(Forkable* forkable) { |
|
|
|
|
grpc_core::MutexLock lock(&g_mu); |
|
|
|
|
g_forkables.erase(forkable); |
|
|
|
|
grpc_core::MutexLock lock(g_mu.get()); |
|
|
|
|
g_forkables->erase(forkable); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace experimental
|
|
|
|
|