OSDN Git Service

Refactor prop_area into a class
authorTom Cherry <tomcherry@google.com>
Wed, 23 Sep 2015 22:34:40 +0000 (15:34 -0700)
committerTom Cherry <tomcherry@google.com>
Tue, 10 Nov 2015 01:22:44 +0000 (17:22 -0800)
Bug 21852512

Change-Id: I432bf592f1a71a046c32616fc334ad77c220f0ca

libc/bionic/system_properties.cpp

index c436a16..9fe982a 100644 (file)
@@ -112,23 +112,57 @@ private:
     DISALLOW_COPY_AND_ASSIGN(prop_bt);
 };
 
-struct prop_area {
-    uint32_t bytes_used;
-    atomic_uint_least32_t serial;
-    uint32_t magic;
-    uint32_t version;
-    uint32_t reserved[28];
-    char data[0];
+class prop_area {
+public:
 
     prop_area(const uint32_t magic, const uint32_t version) :
-        magic(magic), version(version) {
-        atomic_init(&serial, 0);
-        memset(reserved, 0, sizeof(reserved));
+        magic_(magic), version_(version) {
+        atomic_init(&serial_, 0);
+        memset(reserved_, 0, sizeof(reserved_));
         // Allocate enough space for the root node.
-        bytes_used = sizeof(prop_bt);
+        bytes_used_ = sizeof(prop_bt);
     }
 
+    const prop_info *find(const char *name);
+    bool add(const char *name, unsigned int namelen,
+             const char *value, unsigned int valuelen);
+
+    bool foreach(void (*propfn)(const prop_info *pi, void *cookie), void *cookie);
+
+    atomic_uint_least32_t *serial() { return &serial_; }
+    uint32_t magic() const { return magic_; }
+    uint32_t version() const { return version_; }
+
 private:
+    void *allocate_obj(const size_t size, uint_least32_t *const off);
+    prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off);
+    prop_info *new_prop_info(const char *name, uint8_t namelen,
+                             const char *value, uint8_t valuelen,
+                             uint_least32_t *const off);
+    void *to_prop_obj(uint_least32_t off);
+    prop_bt *to_prop_bt(atomic_uint_least32_t *off_p);
+    prop_info *to_prop_info(atomic_uint_least32_t *off_p);
+
+    prop_bt *root_node();
+
+    prop_bt *find_prop_bt(prop_bt *const bt, const char *name,
+                          uint8_t namelen, bool alloc_if_needed);
+
+    const prop_info *find_property(prop_bt *const trie, const char *name,
+                                   uint8_t namelen, const char *value,
+                                   uint8_t valuelen, bool alloc_if_needed);
+
+    bool foreach_property(prop_bt *const trie,
+                          void (*propfn)(const prop_info *pi, void *cookie),
+                          void *cookie);
+
+    uint32_t bytes_used_;
+    atomic_uint_least32_t serial_;
+    uint32_t magic_;
+    uint32_t version_;
+    uint32_t reserved_[28];
+    char data_[0];
+
     DISALLOW_COPY_AND_ASSIGN(prop_area);
 };
 
@@ -246,13 +280,14 @@ static int map_fd_ro(const int fd) {
     }
 
     prop_area* pa = reinterpret_cast<prop_area*>(map_result);
-    if ((pa->magic != PROP_AREA_MAGIC) || (pa->version != PROP_AREA_VERSION &&
-                pa->version != PROP_AREA_VERSION_COMPAT)) {
+    if ((pa->magic() != PROP_AREA_MAGIC) ||
+        (pa->version() != PROP_AREA_VERSION &&
+         pa->version() != PROP_AREA_VERSION_COMPAT)) {
         munmap(pa, pa_size);
         return -1;
     }
 
-    if (pa->version == PROP_AREA_VERSION_COMPAT) {
+    if (pa->version() == PROP_AREA_VERSION_COMPAT) {
         compat_mode = true;
     }
 
@@ -290,20 +325,19 @@ static int map_prop_area()
     return map_result;
 }
 
-static void *allocate_obj(const size_t size, uint_least32_t *const off)
+void *prop_area::allocate_obj(const size_t size, uint_least32_t *const off)
 {
-    prop_area *pa = __system_property_area__;
     const size_t aligned = BIONIC_ALIGN(size, sizeof(uint_least32_t));
-    if (pa->bytes_used + aligned > pa_data_size) {
+    if (bytes_used_ + aligned > pa_data_size) {
         return NULL;
     }
 
-    *off = pa->bytes_used;
-    pa->bytes_used += aligned;
-    return pa->data + *off;
+    *off = bytes_used_;
+    bytes_used_ += aligned;
+    return data_ + *off;
 }
 
-static prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off)
+prop_bt *prop_area::new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off)
 {
     uint_least32_t new_offset;
     void *const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset);
@@ -316,7 +350,7 @@ static prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *c
     return NULL;
 }
 
-static prop_info *new_prop_info(const char *name, uint8_t namelen,
+prop_info *prop_area::new_prop_info(const char *name, uint8_t namelen,
         const char *value, uint8_t valuelen, uint_least32_t *const off)
 {
     uint_least32_t new_offset;
@@ -330,27 +364,25 @@ static prop_info *new_prop_info(const char *name, uint8_t namelen,
     return NULL;
 }
 
-static void *to_prop_obj(uint_least32_t off)
+void *prop_area::to_prop_obj(uint_least32_t off)
 {
     if (off > pa_data_size)
         return NULL;
-    if (!__system_property_area__)
-        return NULL;
 
-    return (__system_property_area__->data + off);
+    return (data_ + off);
 }
 
-static inline prop_bt *to_prop_bt(atomic_uint_least32_t* off_p) {
+inline prop_bt *prop_area::to_prop_bt(atomic_uint_least32_t* off_p) {
   uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
   return reinterpret_cast<prop_bt*>(to_prop_obj(off));
 }
 
-static inline prop_info *to_prop_info(atomic_uint_least32_t* off_p) {
+inline prop_info *prop_area::to_prop_info(atomic_uint_least32_t* off_p) {
   uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
   return reinterpret_cast<prop_info*>(to_prop_obj(off));
 }
 
-static inline prop_bt *root_node()
+inline prop_bt *prop_area::root_node()
 {
     return reinterpret_cast<prop_bt*>(to_prop_obj(0));
 }
@@ -366,8 +398,8 @@ static int cmp_prop_name(const char *one, uint8_t one_len, const char *two,
         return strncmp(one, two, one_len);
 }
 
-static prop_bt *find_prop_bt(prop_bt *const bt, const char *name,
-                             uint8_t namelen, bool alloc_if_needed)
+prop_bt *prop_area::find_prop_bt(prop_bt *const bt, const char *name,
+                                 uint8_t namelen, bool alloc_if_needed)
 {
 
     prop_bt* current = bt;
@@ -417,7 +449,7 @@ static prop_bt *find_prop_bt(prop_bt *const bt, const char *name,
     }
 }
 
-static const prop_info *find_property(prop_bt *const trie, const char *name,
+const prop_info *prop_area::find_property(prop_bt *const trie, const char *name,
         uint8_t namelen, const char *value, uint8_t valuelen,
         bool alloc_if_needed)
 {
@@ -543,39 +575,52 @@ static void find_nth_fn(const prop_info *pi, void *ptr)
     cookie->count++;
 }
 
-static int foreach_property(prop_bt *const trie,
+bool prop_area::foreach_property(prop_bt *const trie,
         void (*propfn)(const prop_info *pi, void *cookie), void *cookie)
 {
     if (!trie)
-        return -1;
+        return false;
 
     uint_least32_t left_offset = atomic_load_explicit(&trie->left, memory_order_relaxed);
     if (left_offset != 0) {
         const int err = foreach_property(to_prop_bt(&trie->left), propfn, cookie);
         if (err < 0)
-            return -1;
+            return false;
     }
     uint_least32_t prop_offset = atomic_load_explicit(&trie->prop, memory_order_relaxed);
     if (prop_offset != 0) {
         prop_info *info = to_prop_info(&trie->prop);
         if (!info)
-            return -1;
+            return false;
         propfn(info, cookie);
     }
     uint_least32_t children_offset = atomic_load_explicit(&trie->children, memory_order_relaxed);
     if (children_offset != 0) {
         const int err = foreach_property(to_prop_bt(&trie->children), propfn, cookie);
         if (err < 0)
-            return -1;
+            return false;
     }
     uint_least32_t right_offset = atomic_load_explicit(&trie->right, memory_order_relaxed);
     if (right_offset != 0) {
         const int err = foreach_property(to_prop_bt(&trie->right), propfn, cookie);
         if (err < 0)
-            return -1;
+            return false;
     }
 
-    return 0;
+    return true;
+}
+
+const prop_info *prop_area::find(const char *name) {
+    return find_property(root_node(), name, strlen(name), nullptr, 0, false);
+}
+
+bool prop_area::add(const char *name, unsigned int namelen,
+                    const char *value, unsigned int valuelen) {
+    return find_property(root_node(), name, namelen, value, valuelen, true);
+}
+
+bool prop_area::foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
+    return foreach_property(root_node(), propfn, cookie);
 }
 
 int __system_properties_init()
@@ -605,7 +650,7 @@ unsigned int __system_property_area_serial()
         return -1;
     }
     // Make sure this read fulfilled before __system_property_serial
-    return atomic_load_explicit(&(pa->serial), memory_order_acquire);
+    return atomic_load_explicit(pa->serial(), memory_order_acquire);
 }
 
 const prop_info *__system_property_find(const char *name)
@@ -613,7 +658,12 @@ const prop_info *__system_property_find(const char *name)
     if (__predict_false(compat_mode)) {
         return __system_property_find_compat(name);
     }
-    return find_property(root_node(), name, strlen(name), NULL, 0, false);
+
+    if (!__system_property_area__) {
+        return nullptr;
+    }
+
+    return __system_property_area__->find(name);
 }
 
 // The C11 standard doesn't allow atomic loads from const fields,
@@ -708,10 +758,10 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len)
     __futex_wake(&pi->serial, INT32_MAX);
 
     atomic_store_explicit(
-        &pa->serial,
-        atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1,
+        pa->serial(),
+        atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1,
         memory_order_release);
-    __futex_wake(&pa->serial, INT32_MAX);
+    __futex_wake(pa->serial(), INT32_MAX);
 
     return 0;
 }
@@ -720,7 +770,6 @@ int __system_property_add(const char *name, unsigned int namelen,
             const char *value, unsigned int valuelen)
 {
     prop_area *pa = __system_property_area__;
-    const prop_info *pi;
 
     if (namelen >= PROP_NAME_MAX)
         return -1;
@@ -729,17 +778,21 @@ int __system_property_add(const char *name, unsigned int namelen,
     if (namelen < 1)
         return -1;
 
-    pi = find_property(root_node(), name, namelen, value, valuelen, true);
-    if (!pi)
+    if (!__system_property_area__) {
+        return -1;
+    }
+
+    bool ret = __system_property_area__->add(name, namelen, value, valuelen);
+    if (!ret)
         return -1;
 
     // There is only a single mutator, but we want to make sure that
     // updates are visible to a reader waiting for the update.
     atomic_store_explicit(
-        &pa->serial,
-        atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1,
+        pa->serial(),
+        atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1,
         memory_order_release);
-    __futex_wake(&pa->serial, INT32_MAX);
+    __futex_wake(pa->serial(), INT32_MAX);
     return 0;
 }
 
@@ -762,8 +815,8 @@ unsigned int __system_property_wait_any(unsigned int serial)
     uint32_t my_serial;
 
     do {
-        __futex_wait(&pa->serial, serial, NULL);
-        my_serial = atomic_load_explicit(&pa->serial, memory_order_acquire);
+        __futex_wait(pa->serial(), serial, NULL);
+        my_serial = atomic_load_explicit(pa->serial(), memory_order_acquire);
     } while (my_serial == serial);
 
     return my_serial;
@@ -788,5 +841,9 @@ int __system_property_foreach(void (*propfn)(const prop_info *pi, void *cookie),
         return __system_property_foreach_compat(propfn, cookie);
     }
 
-    return foreach_property(root_node(), propfn, cookie);
+    if (!__system_property_area__) {
+        return -1;
+    }
+
+    return __system_property_area__->foreach(propfn, cookie) ? 0 : -1;
 }