/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include namespace { using namespace apache::thrift; using namespace apache::thrift::detail; class FlagsRegistry { public: void registerInt64Flag( const std::string_view& flagName, FlagWrapper* flag) { int64Flags_.wlock()->emplace(flagName, flag); } void registerBoolFlag( const std::string_view& flagName, FlagWrapper* flag) { boolFlags_.wlock()->emplace(flagName, flag); } void registerStringFlag( const std::string_view& flagName, FlagWrapper* flag) { stringFlags_.wlock()->emplace(flagName, flag); } std::vector getAllThriftFlags() { std::vector flags; int64Flags_.withRLock([&](auto& locked) { for (auto& [name, flagWrapper] : locked) { flags.push_back( {std::string{name}, std::to_string(flagWrapper->get())}); } }); boolFlags_.withRLock([&](auto& locked) { for (auto& [name, value] : locked) { flags.push_back({std::string{name}, value->get() ? "true" : "false"}); } }); stringFlags_.withRLock([&](auto& locked) { for (auto& [name, value] : locked) { flags.push_back({std::string{name}, value->get()}); } }); return flags; } private: folly::Synchronized*>> int64Flags_; folly::Synchronized*>> boolFlags_; folly::Synchronized*>> stringFlags_; }; FlagsRegistry* getFlagsRegistry() { static folly::Indestructible registry; return registry.get(); } } // namespace namespace apache { namespace thrift { namespace detail { namespace { class FlagsBackendDummy : public apache::thrift::detail::FlagsBackend { public: folly::observer::Observer> getFlagObserverBool( std::string_view name) override { static const folly::Indestructible> oss_defaults = std::map{ {"server_header_reject_framed", false}, {"server_header_reject_unframed", false}, {"server_header_reject_all", false}}; return folly::observer::makeObserver( [name = std::string(name)]() -> std::optional { return folly::get_optional(*oss_defaults, name); }); } folly::observer::Observer> getFlagObserverInt64( std::string_view) override { return folly::observer::makeObserver( []() -> std::optional { return std::nullopt; }); } folly::observer::Observer> getFlagObserverString( std::string_view) override { return folly::observer::makeObserver( []() -> std::optional { return std::nullopt; }); } }; } // namespace THRIFT_PLUGGABLE_FUNC_REGISTER( std::unique_ptr, createFlagsBackend) { return {}; } apache::thrift::detail::FlagsBackend& getFlagsBackend() { static auto& obj = *[] { auto backend = createFlagsBackend(); if (!backend) { backend = std::make_unique(); } return backend.release(); }(); return obj; } template <> void registerFlagWrapper( std::string_view name, FlagWrapper* wrapper) { getFlagsRegistry()->registerInt64Flag(name, wrapper); } template <> void registerFlagWrapper( std::string_view name, FlagWrapper* wrapper) { getFlagsRegistry()->registerBoolFlag(name, wrapper); } template <> void registerFlagWrapper( std::string_view name, FlagWrapper* wrapper) { getFlagsRegistry()->registerStringFlag(name, wrapper); } } // namespace detail std::vector getAllThriftFlags() { return getFlagsRegistry()->getAllThriftFlags(); } } // namespace thrift } // namespace apache