}
uint32_t __system_property_wait_any(uint32_t old_serial) {
- prop_area* pa = __system_property_area__;
- if (!pa) return 0;
-
uint32_t new_serial;
- do {
- __futex_wait(pa->serial(), old_serial, nullptr);
- new_serial = atomic_load_explicit(pa->serial(), memory_order_acquire);
- } while (new_serial == old_serial);
+ __system_property_wait(nullptr, old_serial, &new_serial, nullptr);
return new_serial;
}
-uint32_t __system_property_wait(const prop_info* pi, uint32_t old_serial) {
+bool __system_property_wait(const prop_info* pi,
+ uint32_t old_serial,
+ uint32_t* new_serial_ptr,
+ const timespec* relative_timeout) {
+ // Are we waiting on the global serial or a specific serial?
+ atomic_uint_least32_t* serial_ptr;
+ if (pi == nullptr) {
+ if (__system_property_area__ == nullptr) return -1;
+ serial_ptr = __system_property_area__->serial();
+ } else {
+ serial_ptr = const_cast<atomic_uint_least32_t*>(&pi->serial);
+ }
+
uint32_t new_serial;
do {
- __futex_wait(const_cast<_Atomic(uint_least32_t)*>(&pi->serial), old_serial, nullptr);
- new_serial = load_const_atomic(&pi->serial, memory_order_acquire);
+ int rc;
+ if ((rc = __futex_wait(serial_ptr, old_serial, relative_timeout)) != 0 && rc == -ETIMEDOUT) {
+ return false;
+ }
+ new_serial = load_const_atomic(serial_ptr, memory_order_acquire);
} while (new_serial == old_serial);
- return new_serial;
+
+ *new_serial_ptr = new_serial;
+ return true;
}
const prop_info* __system_property_find_nth(unsigned n) {
#define _INCLUDE_SYS__SYSTEM_PROPERTIES_H
#include <sys/cdefs.h>
+#include <stdbool.h>
#include <stdint.h>
#ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
uint32_t __system_property_serial(const prop_info* pi);
/*
- * Waits for any system property to be updated past `old_serial`.
- * If you don't know the current global serial number, use 0.
- * Returns the new global serial number.
- */
-uint32_t __system_property_wait_any(uint32_t old_serial);
-
-/*
- * Waits for the specific system property identified by `pi` to be updated past `old_serial`.
+ * Waits for the specific system property identified by `pi` to be updated
+ * past `old_serial`. Waits no longer than `relative_timeout`, or forever
+ * if `relaive_timeout` is null.
+ *
+ * If `pi` is null, waits for the global serial number instead.
+ *
* If you don't know the current serial, use 0.
- * Returns the serial number for `pi` that caused the wake.
+ *
+ * Returns true and updates `*new_serial_ptr` on success, or false if the call
+ * timed out.
*/
-uint32_t __system_property_wait(const prop_info* pi, uint32_t old_serial)
+struct timespec;
+bool __system_property_wait(const prop_info* pi,
+ uint32_t old_serial,
+ uint32_t* new_serial_ptr,
+ const struct timespec* relative_timeout)
__INTRODUCED_IN_FUTURE;
/* Initialize the system properties area in read only mode.
*/
int __system_properties_init();
+/* Deprecated: use __system_property_wait instead. */
+uint32_t __system_property_wait_any(uint32_t old_serial);
+
__END_DECLS
#endif
__system_property_update(pi, "value2", 6);
});
- __system_property_wait(pi, serial);
+ uint32_t new_serial;
+ __system_property_wait(pi, serial, &new_serial, nullptr);
+ ASSERT_GT(new_serial, serial);
char value[PROP_VALUE_MAX];
ASSERT_EQ(6, __system_property_get("property", value));