Files
apache--brpc/test/brpc_adaptive_class_unittest.cpp
Felix-Gong e9d4b190fb Fix static initialization order fiasco in AdaptiveMaxConcurrency (#3315)
AdaptiveMaxConcurrency has two class-static std::string members (UNLIMITED
and CONSTANT) defined in adaptive_max_concurrency.cpp. Global
AdaptiveMaxConcurrency objects in other translation units may be constructed
before these static strings are initialized, causing undefined behavior.

This issue was discovered during RISC-V porting and testing of BRPC.
Different toolchains and linkers (GCC, Clang, cross-compilation toolchains
for RISC-V, etc.) may produce different static initialization orders, making
this bug manifest on some platforms but not others.

Fix by replacing class-static std::string members with Meyers' Singleton
pattern (function-local statics), which C++11 guarantees are initialized
on first use in a thread-safe manner.

This fix benefits all architectures including x86_64, ARM64, and RISC-V.

Signed-off-by: Felix-Gong <gongxiaofei24@iscas.ac.cn>
2026-05-29 15:29:04 +08:00

76 lines
2.6 KiB
C++

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.
// brpc - A framework to host and access services throughout Baidu.
// Date: 2019/04/16 23:41:04
#include <gtest/gtest.h>
#include "brpc/adaptive_max_concurrency.h"
#include "brpc/adaptive_protocol_type.h"
#include "brpc/adaptive_connection_type.h"
const std::string kAutoCL = "aUto";
const std::string kHttp = "hTTp";
const std::string kPooled = "PoOled";
TEST(AdaptiveMaxConcurrencyTest, ShouldConvertCorrectly) {
brpc::AdaptiveMaxConcurrency amc(0);
EXPECT_EQ(brpc::AdaptiveMaxConcurrency::UNLIMITED(), amc.type());
EXPECT_EQ(brpc::AdaptiveMaxConcurrency::UNLIMITED(), amc.value());
EXPECT_EQ(0, int(amc));
EXPECT_TRUE(amc == brpc::AdaptiveMaxConcurrency::UNLIMITED());
amc = 10;
EXPECT_EQ(brpc::AdaptiveMaxConcurrency::CONSTANT(), amc.type());
EXPECT_EQ("10", amc.value());
EXPECT_EQ(10, int(amc));
EXPECT_EQ(amc, "10");
amc = kAutoCL;
EXPECT_EQ(kAutoCL, amc.type());
EXPECT_EQ(kAutoCL, amc.value());
EXPECT_EQ(int(amc), -1);
EXPECT_TRUE(amc == "auto");
}
TEST(AdaptiveProtocolTypeTest, ShouldConvertCorrectly) {
brpc::AdaptiveProtocolType apt;
apt = kHttp;
EXPECT_EQ(apt, brpc::ProtocolType::PROTOCOL_HTTP);
EXPECT_NE(apt, brpc::ProtocolType::PROTOCOL_BAIDU_STD);
apt = brpc::ProtocolType::PROTOCOL_HTTP;
EXPECT_EQ(apt, brpc::ProtocolType::PROTOCOL_HTTP);
EXPECT_NE(apt, brpc::ProtocolType::PROTOCOL_BAIDU_STD);
}
TEST(AdaptiveConnectionTypeTest, ShouldConvertCorrectly) {
brpc::AdaptiveConnectionType act;
act = brpc::ConnectionType::CONNECTION_TYPE_POOLED;
EXPECT_EQ(act, brpc::ConnectionType::CONNECTION_TYPE_POOLED);
EXPECT_NE(act, brpc::ConnectionType::CONNECTION_TYPE_SINGLE);
act = kPooled;
EXPECT_EQ(act, brpc::ConnectionType::CONNECTION_TYPE_POOLED);
EXPECT_NE(act, brpc::ConnectionType::CONNECTION_TYPE_SINGLE);
}