From 68e9b6bc947eaca4135085615860ba90a8656ca4 Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Wed, 13 Feb 2013 10:49:50 -0800 Subject: [PATCH] toolbox: reimplement watchprops using __system_property_foreach() Internally, replace the watchlist array with a hashmap since the array assumes properties are enumerated in a consistent order and foreach() probably won't. (find_nth() never guaranteed this either but it usually worked in practice.) Signed-off-by: Greg Hackmann (cherry picked from commit 389e358017ad15485f2bd9120feebfffa489131b) Change-Id: I1db3137b130474f4bb205f01f0bdcf37cf974764 --- toolbox/watchprops.c | 100 ++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 40 deletions(-) diff --git a/toolbox/watchprops.c b/toolbox/watchprops.c index 3418d6293..bf82882f1 100644 --- a/toolbox/watchprops.c +++ b/toolbox/watchprops.c @@ -1,32 +1,30 @@ #include #include #include +#include #include +#include #include #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ #include -typedef struct pwatch pwatch; - -struct pwatch +static int str_hash(void *key) { - const prop_info *pi; - unsigned serial; -}; + return hashmapHash(key, strlen(key)); +} -static pwatch watchlist[1024]; - -static void announce(const prop_info *pi) +static bool str_equals(void *keyA, void *keyB) +{ + return strcmp(keyA, keyB) == 0; +} + +static void announce(char *name, char *value) { - char name[PROP_NAME_MAX]; - char value[PROP_VALUE_MAX]; char *x; - __system_property_read(pi, name, value); - for(x = value; *x; x++) { if((*x < 32) || (*x > 127)) *x = '.'; } @@ -34,42 +32,64 @@ static void announce(const prop_info *pi) fprintf(stderr,"%10d %s = '%s'\n", (int) time(0), name, value); } +static void add_to_watchlist(Hashmap *watchlist, const char *name, + const prop_info *pi) +{ + char *key = strdup(name); + unsigned *value = malloc(sizeof(unsigned)); + if (!key || !value) + exit(1); + + *value = __system_property_serial(pi); + hashmapPut(watchlist, key, value); +} + +static void populate_watchlist(const prop_info *pi, void *cookie) +{ + Hashmap *watchlist = cookie; + char name[PROP_NAME_MAX]; + char value_unused[PROP_VALUE_MAX]; + + __system_property_read(pi, name, value_unused); + add_to_watchlist(watchlist, name, pi); +} + +static void update_watchlist(const prop_info *pi, void *cookie) +{ + Hashmap *watchlist = cookie; + char name[PROP_NAME_MAX]; + char value[PROP_VALUE_MAX]; + unsigned *serial; + + __system_property_read(pi, name, value); + serial = hashmapGet(watchlist, name); + if (!serial) { + add_to_watchlist(watchlist, name, pi); + announce(name, value); + } else { + unsigned tmp = __system_property_serial(pi); + if (*serial != tmp) { + *serial = tmp; + announce(name, value); + } + } +} + int watchprops_main(int argc, char *argv[]) { unsigned serial = 0; - unsigned count; + unsigned count = 0; unsigned n; - for(n = 0; n < 1024; n++) { - watchlist[n].pi = __system_property_find_nth(n); - if (watchlist[n].pi == 0) - break; - watchlist[n].serial = __system_property_serial(watchlist[n].pi); - } - - count = n; - if (count == 1024) + Hashmap *watchlist = hashmapCreate(1024, str_hash, str_equals); + if (!watchlist) exit(1); + __system_property_foreach(populate_watchlist, watchlist); + for(;;) { serial = __system_property_wait_any(serial); - while(count < 1024){ - watchlist[count].pi = __system_property_find_nth(count); - if (watchlist[count].pi == 0) - break; - watchlist[count].serial = __system_property_serial(watchlist[n].pi); - announce(watchlist[count].pi); - count++; - if(count == 1024) exit(1); - } - - for(n = 0; n < count; n++){ - unsigned tmp = __system_property_serial(watchlist[n].pi); - if(watchlist[n].serial != tmp) { - announce(watchlist[n].pi); - watchlist[n].serial = tmp; - } - } + __system_property_foreach(update_watchlist, watchlist); } return 0; }