OSDN Git Service

Add timeout support to __system_property_wait.
authorElliott Hughes <enh@google.com>
Fri, 17 Feb 2017 01:13:04 +0000 (17:13 -0800)
committerElliott Hughes <enh@google.com>
Tue, 21 Feb 2017 22:36:24 +0000 (14:36 -0800)
Bug: http://b/35201172
Test: ran tests
Change-Id: I3a78813bf3cd50d1b308ecb3c742f923606c0cc4

libc/bionic/system_properties.cpp
libc/include/sys/_system_properties.h
tests/system_properties_test.cpp

index 32d1e31..0f2a7b5 100644 (file)
@@ -1341,24 +1341,35 @@ uint32_t __system_property_serial(const prop_info* pi) {
 }
 
 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) {
index fa98d11..186d390 100644 (file)
@@ -30,6 +30,7 @@
 #define _INCLUDE_SYS__SYSTEM_PROPERTIES_H
 
 #include <sys/cdefs.h>
+#include <stdbool.h>
 #include <stdint.h>
 
 #ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
@@ -122,18 +123,22 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len)
 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.
@@ -144,6 +149,9 @@ uint32_t __system_property_wait(const prop_info* pi, uint32_t old_serial)
  */
 int __system_properties_init();
 
+/* Deprecated: use __system_property_wait instead. */
+uint32_t __system_property_wait_any(uint32_t old_serial);
+
 __END_DECLS
 
 #endif
index 39734d7..ff97549 100644 (file)
@@ -402,7 +402,9 @@ TEST(properties, __system_property_wait) {
         __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));