Loading base/include/android-base/properties.h +3 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,9 @@ template <typename T> T GetUintProperty(const std::string& key, // tell you whether or not your call succeeded. A `false` return value definitely means failure. bool SetProperty(const std::string& key, const std::string& value); // Waits for the system property `key` to have the value `expected_value`, . void WaitForProperty(const std::string& key, const std::string& expected_value); } // namespace base } // namespace android Loading base/properties.cpp +41 −0 Original line number Diff line number Diff line Loading @@ -14,9 +14,12 @@ * limitations under the License. */ #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ #include "android-base/properties.h" #include <sys/system_properties.h> #include <sys/_system_properties.h> #include <string> Loading Loading @@ -78,5 +81,43 @@ bool SetProperty(const std::string& key, const std::string& value) { return (__system_property_set(key.c_str(), value.c_str()) == 0); } struct WaitForPropertyData { bool done; const std::string* expected_value; unsigned last_read_serial; }; static void WaitForPropertyCallback(void* data_ptr, const char*, const char* value, unsigned serial) { WaitForPropertyData* data = reinterpret_cast<WaitForPropertyData*>(data_ptr); if (*data->expected_value == value) { data->done = true; } else { data->last_read_serial = serial; } } void WaitForProperty(const std::string& key, const std::string& expected_value) { // Find the property's prop_info*. const prop_info* pi; unsigned global_serial = 0; while ((pi = __system_property_find(key.c_str())) == nullptr) { // The property doesn't even exist yet. // Wait for a global change and then look again. global_serial = __system_property_wait_any(global_serial); } WaitForPropertyData data; data.expected_value = &expected_value; data.done = false; while (true) { // Check whether the property has the value we're looking for? __system_property_read_callback(pi, WaitForPropertyCallback, &data); if (data.done) return; // It didn't so wait for it to change before checking again. __system_property_wait(pi, data.last_read_serial); } } } // namespace base } // namespace android base/properties_test.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,12 @@ #include <gtest/gtest.h> #include <atomic> #include <chrono> #include <string> #include <thread> using namespace std::chrono_literals; TEST(properties, smoke) { android::base::SetProperty("debug.libbase.property_test", "hello"); Loading Loading @@ -119,3 +124,18 @@ TEST(properties, GetUintProperty_uint8_t) { CheckGetUintProperty<uint8_t>(); } TEST(properties, GetUintProperty_uint16_t) { CheckGetUintProperty<uint16_t>(); } TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); } TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); } TEST(properties, WaitForProperty) { std::atomic<bool> flag{false}; std::thread thread([&]() { std::this_thread::sleep_for(100ms); android::base::SetProperty("debug.libbase.WaitForProperty_test", "a"); while (!flag) std::this_thread::yield(); android::base::SetProperty("debug.libbase.WaitForProperty_test", "b"); }); android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a"); flag = true; android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b"); thread.join(); } libcutils/properties.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ struct callback_data { void* cookie; }; static void trampoline(void* raw_data, const char* name, const char* value) { static void trampoline(void* raw_data, const char* name, const char* value, unsigned /*serial*/) { callback_data* data = reinterpret_cast<callback_data*>(raw_data); data->callback(name, value, data->cookie); } Loading Loading
base/include/android-base/properties.h +3 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,9 @@ template <typename T> T GetUintProperty(const std::string& key, // tell you whether or not your call succeeded. A `false` return value definitely means failure. bool SetProperty(const std::string& key, const std::string& value); // Waits for the system property `key` to have the value `expected_value`, . void WaitForProperty(const std::string& key, const std::string& expected_value); } // namespace base } // namespace android Loading
base/properties.cpp +41 −0 Original line number Diff line number Diff line Loading @@ -14,9 +14,12 @@ * limitations under the License. */ #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ #include "android-base/properties.h" #include <sys/system_properties.h> #include <sys/_system_properties.h> #include <string> Loading Loading @@ -78,5 +81,43 @@ bool SetProperty(const std::string& key, const std::string& value) { return (__system_property_set(key.c_str(), value.c_str()) == 0); } struct WaitForPropertyData { bool done; const std::string* expected_value; unsigned last_read_serial; }; static void WaitForPropertyCallback(void* data_ptr, const char*, const char* value, unsigned serial) { WaitForPropertyData* data = reinterpret_cast<WaitForPropertyData*>(data_ptr); if (*data->expected_value == value) { data->done = true; } else { data->last_read_serial = serial; } } void WaitForProperty(const std::string& key, const std::string& expected_value) { // Find the property's prop_info*. const prop_info* pi; unsigned global_serial = 0; while ((pi = __system_property_find(key.c_str())) == nullptr) { // The property doesn't even exist yet. // Wait for a global change and then look again. global_serial = __system_property_wait_any(global_serial); } WaitForPropertyData data; data.expected_value = &expected_value; data.done = false; while (true) { // Check whether the property has the value we're looking for? __system_property_read_callback(pi, WaitForPropertyCallback, &data); if (data.done) return; // It didn't so wait for it to change before checking again. __system_property_wait(pi, data.last_read_serial); } } } // namespace base } // namespace android
base/properties_test.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,12 @@ #include <gtest/gtest.h> #include <atomic> #include <chrono> #include <string> #include <thread> using namespace std::chrono_literals; TEST(properties, smoke) { android::base::SetProperty("debug.libbase.property_test", "hello"); Loading Loading @@ -119,3 +124,18 @@ TEST(properties, GetUintProperty_uint8_t) { CheckGetUintProperty<uint8_t>(); } TEST(properties, GetUintProperty_uint16_t) { CheckGetUintProperty<uint16_t>(); } TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); } TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); } TEST(properties, WaitForProperty) { std::atomic<bool> flag{false}; std::thread thread([&]() { std::this_thread::sleep_for(100ms); android::base::SetProperty("debug.libbase.WaitForProperty_test", "a"); while (!flag) std::this_thread::yield(); android::base::SetProperty("debug.libbase.WaitForProperty_test", "b"); }); android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a"); flag = true; android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b"); thread.join(); }
libcutils/properties.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ struct callback_data { void* cookie; }; static void trampoline(void* raw_data, const char* name, const char* value) { static void trampoline(void* raw_data, const char* name, const char* value, unsigned /*serial*/) { callback_data* data = reinterpret_cast<callback_data*>(raw_data); data->callback(name, value, data->cookie); } Loading