void mb__system_property_read_callback(const prop_info* pi, void (*callback)(void* cookie, const char* name, const char* value, uint32_t serial), void* cookie) { #if MB_ENABLE_COMPAT_PROPERTIES // TODO (dimitry): do we need compat mode for this function? if (__predict_false(compat_mode)) { uint32_t serial = mb__system_property_serial_compat(pi); char name_buf[PROP_NAME_MAX]; char value_buf[PROP_VALUE_MAX]; mb__system_property_read_compat(pi, name_buf, value_buf); callback(cookie, name_buf, value_buf, serial); return; } #endif while (true) { uint32_t serial = mb__system_property_serial(pi); // acquire semantics size_t len = SERIAL_VALUE_LEN(serial); char value_buf[len + 1]; memcpy(value_buf, pi->value, len); value_buf[len] = '\0'; // TODO: see todo in __system_property_read function atomic_thread_fence(memory_order_acquire); if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) { callback(cookie, pi->name, value_buf, serial); return; } } }
int mb__system_property_read(const prop_info *pi, char *name, char *value) { if (__predict_false(compat_mode)) { return mb__system_property_read_compat(pi, name, value); } while (true) { uint32_t serial = mb__system_property_serial(pi); // acquire semantics size_t len = SERIAL_VALUE_LEN(serial); memcpy(value, pi->value, len + 1); // TODO: Fix the synchronization scheme here. // There is no fully supported way to implement this kind // of synchronization in C++11, since the memcpy races with // updates to pi, and the data being accessed is not atomic. // The following fence is unintuitive, but would be the // correct one if memcpy used memory_order_relaxed atomic accesses. // In practice it seems unlikely that the generated code would // would be any different, so this should be OK. atomic_thread_fence(memory_order_acquire); if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) { if (name != 0) { strcpy(name, pi->name); } return len; } } }
int mb__system_property_read(const prop_info* pi, char* name, char* value) { #if MB_ENABLE_COMPAT_PROPERTIES if (__predict_false(compat_mode)) { return mb__system_property_read_compat(pi, name, value); } #endif while (true) { uint32_t serial = mb__system_property_serial(pi); // acquire semantics size_t len = SERIAL_VALUE_LEN(serial); memcpy(value, pi->value, len + 1); // TODO: Fix the synchronization scheme here. // There is no fully supported way to implement this kind // of synchronization in C++11, since the memcpy races with // updates to pi, and the data being accessed is not atomic. // The following fence is unintuitive, but would be the // correct one if memcpy used memory_order_relaxed atomic accesses. // In practice it seems unlikely that the generated code would // would be any different, so this should be OK. atomic_thread_fence(memory_order_acquire); if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) { if (name != nullptr) { size_t namelen = strlcpy(name, pi->name, PROP_NAME_MAX); if (namelen >= PROP_NAME_MAX) { LOGE("The property name length for \"%s\" is >= %d;" " please use __system_property_read_callback" " to read this property. (the name is truncated to \"%s\")", pi->name, PROP_NAME_MAX - 1, name); } } return len; } } }