#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/gprpp/memory.h"
/*
* AROUND VERY SPECIFIC USE CASES.
*/
+#ifdef GRPC_ENABLE_FORK_SUPPORT
+#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT true
+#else
+#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT false
+#endif // GRPC_ENABLE_FORK_SUPPORT
+
+GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_enable_fork_support,
+ GRPC_ENABLE_FORK_SUPPORT_DEFAULT,
+ "Enable fork support");
+
namespace grpc_core {
namespace internal {
// The exec_ctx_count has 2 modes, blocked and unblocked.
// When blocked, the exec_ctx_count is 0-indexed. Note that ExecCtx
// creation can only be blocked if there is exactly 1 outstanding ExecCtx,
// meaning that BLOCKED and UNBLOCKED counts partition the integers
-#define UNBLOCKED(n) (n + 2)
+#define UNBLOCKED(n) ((n) + 2)
#define BLOCKED(n) (n)
class ExecCtxState {
int count_;
};
-} // namespace
+} // namespace internal
void Fork::GlobalInit() {
if (!override_enabled_) {
-#ifdef GRPC_ENABLE_FORK_SUPPORT
- support_enabled_ = true;
-#else
- support_enabled_ = false;
-#endif
- bool env_var_set = false;
- char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT");
- if (env != nullptr) {
- static const char* truthy[] = {"yes", "Yes", "YES", "true",
- "True", "TRUE", "1"};
- static const char* falsey[] = {"no", "No", "NO", "false",
- "False", "FALSE", "0"};
- for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) {
- if (0 == strcmp(env, truthy[i])) {
- support_enabled_ = true;
- env_var_set = true;
- break;
- }
- }
- if (!env_var_set) {
- for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) {
- if (0 == strcmp(env, falsey[i])) {
- support_enabled_ = false;
- env_var_set = true;
- break;
- }
- }
- }
- gpr_free(env);
- }
+ support_enabled_.Store(GPR_GLOBAL_CONFIG_GET(grpc_enable_fork_support),
+ MemoryOrder::RELAXED);
}
- if (support_enabled_) {
- exec_ctx_state_ = grpc_core::New<internal::ExecCtxState>();
- thread_state_ = grpc_core::New<internal::ThreadState>();
+ if (support_enabled_.Load(MemoryOrder::RELAXED)) {
+ exec_ctx_state_ = new internal::ExecCtxState();
+ thread_state_ = new internal::ThreadState();
}
}
void Fork::GlobalShutdown() {
- if (support_enabled_) {
- grpc_core::Delete(exec_ctx_state_);
- grpc_core::Delete(thread_state_);
+ if (support_enabled_.Load(MemoryOrder::RELAXED)) {
+ delete exec_ctx_state_;
+ delete thread_state_;
}
}
-bool Fork::Enabled() { return support_enabled_; }
+bool Fork::Enabled() { return support_enabled_.Load(MemoryOrder::RELAXED); }
// Testing Only
void Fork::Enable(bool enable) {
override_enabled_ = true;
- support_enabled_ = enable;
+ support_enabled_.Store(enable, MemoryOrder::RELAXED);
}
-void Fork::IncExecCtxCount() {
- if (support_enabled_) {
- exec_ctx_state_->IncExecCtxCount();
- }
-}
+void Fork::DoIncExecCtxCount() { exec_ctx_state_->IncExecCtxCount(); }
-void Fork::DecExecCtxCount() {
- if (support_enabled_) {
- exec_ctx_state_->DecExecCtxCount();
- }
-}
+void Fork::DoDecExecCtxCount() { exec_ctx_state_->DecExecCtxCount(); }
void Fork::SetResetChildPollingEngineFunc(
Fork::child_postfork_func reset_child_polling_engine) {
}
bool Fork::BlockExecCtx() {
- if (support_enabled_) {
+ if (support_enabled_.Load(MemoryOrder::RELAXED)) {
return exec_ctx_state_->BlockExecCtx();
}
return false;
}
void Fork::AllowExecCtx() {
- if (support_enabled_) {
+ if (support_enabled_.Load(MemoryOrder::RELAXED)) {
exec_ctx_state_->AllowExecCtx();
}
}
void Fork::IncThreadCount() {
- if (support_enabled_) {
+ if (support_enabled_.Load(MemoryOrder::RELAXED)) {
thread_state_->IncThreadCount();
}
}
void Fork::DecThreadCount() {
- if (support_enabled_) {
+ if (support_enabled_.Load(MemoryOrder::RELAXED)) {
thread_state_->DecThreadCount();
}
}
void Fork::AwaitThreads() {
- if (support_enabled_) {
+ if (support_enabled_.Load(MemoryOrder::RELAXED)) {
thread_state_->AwaitThreads();
}
}
internal::ExecCtxState* Fork::exec_ctx_state_ = nullptr;
internal::ThreadState* Fork::thread_state_ = nullptr;
-bool Fork::support_enabled_ = false;
+Atomic<bool> Fork::support_enabled_(false);
bool Fork::override_enabled_ = false;
Fork::child_postfork_func Fork::reset_child_polling_engine_ = nullptr;
} // namespace grpc_core