int __system_property_update(prop_info *pi, const char *value, unsigned int len) { prop_area *pa = __system_property_area__; if (len >= PROP_VALUE_MAX) return -1; uint32_t serial = atomic_load_explicit(&pi->serial, memory_order_relaxed); serial |= 1; atomic_store_explicit(&pi->serial, serial, memory_order_relaxed); // The memcpy call here also races. Again pretend it // used memory_order_relaxed atomics, and use the analogous // counterintuitive fence. atomic_thread_fence(memory_order_release); memcpy(pi->value, value, len + 1); atomic_store_explicit( &pi->serial, (len << 24) | ((serial + 1) & 0xffffff), memory_order_release); __futex_wake(&pi->serial, INT32_MAX); atomic_store_explicit( &pa->serial, atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1, memory_order_release); __futex_wake(&pa->serial, INT32_MAX); return 0; }
int SystemProperties::Update(prop_info* pi, const char* value, unsigned int len) { if (len >= PROP_VALUE_MAX) { return -1; } if (!initialized_) { return -1; } prop_area* pa = contexts_->GetSerialPropArea(); if (!pa) { return -1; } uint32_t serial = atomic_load_explicit(&pi->serial, memory_order_relaxed); serial |= 1; atomic_store_explicit(&pi->serial, serial, memory_order_relaxed); // The memcpy call here also races. Again pretend it // used memory_order_relaxed atomics, and use the analogous // counterintuitive fence. atomic_thread_fence(memory_order_release); strlcpy(pi->value, value, len + 1); atomic_store_explicit(&pi->serial, (len << 24) | ((serial + 1) & 0xffffff), memory_order_release); __futex_wake(&pi->serial, INT32_MAX); atomic_store_explicit(pa->serial(), atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1, memory_order_release); __futex_wake(pa->serial(), INT32_MAX); return 0; }
int property_set(const char *name, const char *value) { prop_area *pa; prop_info *pi; int namelen = strlen(name); int valuelen = strlen(value); if(namelen >= PROP_NAME_MAX) return -1; if(valuelen >= PROP_VALUE_MAX) return -1; if(namelen < 1) return -1; pi = (prop_info*) __system_property_find(name); if(pi != 0) { /* ro.* properties may NEVER be modified once set */ if(!strncmp(name, "ro.", 3)) return -1; pa = __system_property_area__; update_prop_info(pi, value, valuelen); pa->serial++; __futex_wake(&pa->serial, INT32_MAX); } else { pa = __system_property_area__; if(pa->count == PA_COUNT_MAX) return -1; pi = pa_info_array + pa->count; pi->serial = (valuelen << 24); memcpy(pi->name, name, namelen + 1); memcpy(pi->value, value, valuelen + 1); pa->toc[pa->count] = (namelen << 24) | (((unsigned) pi) - ((unsigned) pa)); pa->count++; pa->serial++; __futex_wake(&pa->serial, INT32_MAX); } /* If name starts with "net." treat as a DNS property. */ if (strncmp("net.", name, strlen("net.")) == 0) { if (strcmp("net.change", name) == 0) { return 0; } /* * The 'net.change' property is a special property used track when any * 'net.*' property name is updated. It is _ONLY_ updated here. Its value * contains the last updated 'net.*' property. */ property_set("net.change", name); } else if (persistent_properties_loaded && strncmp("persist.", name, strlen("persist.")) == 0) { /* * Don't write properties to disk until after we have read all default properties * to prevent them from being overwritten by default values. */ write_persistent_property(name, value); } property_changed(name, value); return 0; }
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; if (valuelen >= PROP_VALUE_MAX) return -1; if (namelen < 1) return -1; pi = find_property(root_node(), name, namelen, value, valuelen, true); if (!pi) 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, memory_order_release); __futex_wake(&pa->serial, INT32_MAX); return 0; }
static void update_prop_info(prop_info *pi, const char *value, unsigned len) { pi->serial = pi->serial | 1; memcpy(pi->value, value, len + 1); pi->serial = (len << 24) | ((pi->serial + 1) & 0xffffff); __futex_wake(&pi->serial, INT32_MAX); }
int mb__system_property_add(const char *name, unsigned int namelen, const char *value, unsigned int valuelen) { if (namelen >= PROP_NAME_MAX) return -1; if (valuelen >= PROP_VALUE_MAX) return -1; if (namelen < 1) return -1; if (!mb__system_property_area__) { return -1; } prop_area* pa = get_prop_area_for_name(name); if (!pa) { LOGE("Access denied adding property \"%s\"", name); return -1; } bool ret = pa->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( mb__system_property_area__->serial(), atomic_load_explicit(mb__system_property_area__->serial(), memory_order_relaxed) + 1, memory_order_release); __futex_wake(mb__system_property_area__->serial(), INT32_MAX); return 0; }
static int legacy_property_set(const char *name, const char *value) { prop_area *pa; prop_info *pi; int namelen = strlen(name); int valuelen = strlen(value); if (namelen >= PROP_NAME_MAX) return -1; if (valuelen >= PROP_VALUE_MAX) return -1; if (namelen < 1) return -1; pi = (prop_info*) __legacy_property_find(name); if (pi != 0) { /* ro.* properties may NEVER be modified once set */ if (!strncmp(name, "ro.", 3)) return -1; pa = __legacy_property_area__; update_prop_info(pi, value, valuelen); pa->serial++; __futex_wake(&pa->serial, INT32_MAX); } else { pa = __legacy_property_area__; if (pa->count == PA_COUNT_MAX) return -1; pi = pa_info_array + pa->count; pi->serial = (valuelen << 24); memcpy(pi->name, name, namelen + 1); memcpy(pi->value, value, valuelen + 1); pa->toc[pa->count] = (namelen << 24) | (((unsigned) pi) - ((unsigned) pa)); pa->count++; pa->serial++; __futex_wake(&pa->serial, INT32_MAX); } return 0; }
int __system_property_update(prop_info *pi, const char *value, unsigned int len) { prop_area *pa = __system_property_area__; if (len >= PROP_VALUE_MAX) return -1; pi->serial = pi->serial | 1; ANDROID_MEMBAR_FULL(); memcpy(pi->value, value, len + 1); ANDROID_MEMBAR_FULL(); pi->serial = (len << 24) | ((pi->serial + 1) & 0xffffff); __futex_wake(&pi->serial, INT32_MAX); pa->serial++; __futex_wake(&pa->serial, INT32_MAX); return 0; }
extern "C" void __cxa_guard_release(_guard_t* gv) { // pending -> ready // waiting -> ready, and wake ANDROID_MEMBAR_FULL(); if (__atomic_cmpxchg(pending, ready, &gv->state) == 0) { return; } gv->state = ready; __futex_wake(&gv->state, 0x7fffffff); }
/* * Signal an event. */ BOOL event_signal( EVENT * event ) { if( event == NULL ) return FALSE; #ifdef _WIN32 dprintf( "Signalling 0x%x", event->handle ); if( SetEvent( event->handle ) == 0 ) { dprintf( "Signalling 0x%x failed %u", event->handle, GetLastError() ); return FALSE; } #else event->handle = (HANDLE)1; __futex_wake(&(event->handle), 1); #endif return TRUE; }
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; if (valuelen >= PROP_VALUE_MAX) return -1; if (namelen < 1) return -1; pi = find_property(root_node(), name, namelen, value, valuelen, true); if (!pi) return -1; pa->serial++; __futex_wake(&pa->serial, INT32_MAX); return 0; }
int SystemProperties::Add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen) { if (valuelen >= PROP_VALUE_MAX && !is_read_only(name)) { return -1; } if (namelen < 1) { return -1; } if (!initialized_) { return -1; } prop_area* serial_pa = contexts_->GetSerialPropArea(); if (serial_pa == nullptr) { return -1; } prop_area* pa = contexts_->GetPropAreaForName(name); if (!pa) { async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name); return -1; } bool ret = pa->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(serial_pa->serial(), atomic_load_explicit(serial_pa->serial(), memory_order_relaxed) + 1, memory_order_release); __futex_wake(serial_pa->serial(), INT32_MAX); return 0; }
extern "C" void __cxa_guard_abort(_guard_t* gv) { ANDROID_MEMBAR_FULL(); gv->state= 0; __futex_wake(&gv->state, 0x7fffffff); }