diff --git a/src/platform/common.h b/src/platform/common.h index 5009c18335a..bd594ba1b67 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -612,6 +612,23 @@ namespace platf { void restart(); + /** + * @brief Set an environment variable. + * @param name The name of the environment variable. + * @param value The value to set the environment variable to. + * @return 0 on success, non-zero on failure. + */ + int + set_env(const std::string &name, const std::string &value); + + /** + * @brief Unset an environment variable. + * @param name The name of the environment variable. + * @return 0 on success, non-zero on failure. + */ + int + unset_env(const std::string &name); + struct buffer_descriptor_t { const char *buffer; size_t size; diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 9997c4055de..b3e31ec697b 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -326,6 +326,16 @@ namespace platf { lifetime::exit_sunshine(0, true); } + int + set_env(const std::string &name, const std::string &value) { + return setenv(name.c_str(), value.c_str(), 1); + } + + int + unset_env(const std::string &name) { + return unsetenv(name.c_str()); + } + bool request_process_group_exit(std::uintptr_t native_handle) { if (kill(-((pid_t) native_handle), SIGTERM) == 0 || errno == ESRCH) { @@ -913,6 +923,10 @@ namespace platf { std::unique_ptr init() { + // enable low latency mode for AMD + // https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30039 + set_env("AMD_DEBUG", "lowlatency"); + // These are allowed to fail. gbm::init(); diff --git a/src/platform/macos/misc.mm b/src/platform/macos/misc.mm index f03dd3bfb5c..6eca7d2e33f 100644 --- a/src/platform/macos/misc.mm +++ b/src/platform/macos/misc.mm @@ -253,6 +253,16 @@ lifetime::exit_sunshine(0, true); } + int + set_env(const std::string &name, const std::string &value) { + return setenv(name.c_str(), value.c_str(), 1); + } + + int + unset_env(const std::string &name) { + return unsetenv(name.c_str()); + } + bool request_process_group_exit(std::uintptr_t native_handle) { if (killpg((pid_t) native_handle, SIGTERM) == 0 || errno == ESRCH) { diff --git a/src/platform/windows/misc.cpp b/src/platform/windows/misc.cpp index a4190e01708..657807fa05c 100644 --- a/src/platform/windows/misc.cpp +++ b/src/platform/windows/misc.cpp @@ -1313,6 +1313,16 @@ namespace platf { lifetime::exit_sunshine(0, true); } + int + set_env(const std::string &name, const std::string &value) { + return _putenv_s(name.c_str(), value.c_str()); + } + + int + unset_env(const std::string &name) { + return _putenv_s(name.c_str(), ""); + } + struct enum_wnd_context_t { std::set process_ids; bool requested_exit; diff --git a/tests/unit/platform/test_common.cpp b/tests/unit/platform/test_common.cpp new file mode 100644 index 00000000000..6f1c9becfb6 --- /dev/null +++ b/tests/unit/platform/test_common.cpp @@ -0,0 +1,49 @@ +/** + * @file tests/unit/platform/test_common.cpp + * @brief Test src/platform/common.*. + */ +#include + +#include "../../tests_common.h" + +struct SetEnvTest: ::testing::TestWithParam> { +protected: + void + TearDown() override { + // Clean up environment variable after each test + const auto &[name, value, expected] = GetParam(); + platf::unset_env(name); + } +}; + +TEST_P(SetEnvTest, SetEnvironmentVariableTests) { + const auto &[name, value, expected] = GetParam(); + platf::set_env(name, value); + + const char *env_value = std::getenv(name.c_str()); + if (expected == 0 && !value.empty()) { + ASSERT_NE(env_value, nullptr); + ASSERT_EQ(std::string(env_value), value); + } + else { + ASSERT_EQ(env_value, nullptr); + } +} + +TEST_P(SetEnvTest, UnsetEnvironmentVariableTests) { + const auto &[name, value, expected] = GetParam(); + platf::unset_env(name); + + const char *env_value = std::getenv(name.c_str()); + if (expected == 0) { + ASSERT_EQ(env_value, nullptr); + } +} + +INSTANTIATE_TEST_SUITE_P( + SetEnvTests, + SetEnvTest, + ::testing::Values( + std::make_tuple("SUNSHINE_UNIT_TEST_ENV_VAR", "test_value_0", 0), + std::make_tuple("SUNSHINE_UNIT_TEST_ENV_VAR", "test_value_1", 0), + std::make_tuple("", "test_value", -1)));