Merge change 23892 into eclair

* changes:
  android_atomic_write() implementation was using cmpxchg which was useless
diff --git a/adb/services.c b/adb/services.c
index 2864ac9..cd02b36 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -32,8 +32,7 @@
 #    include <netdb.h>
 #  endif
 #else
-#include <sys/poll.h>
-#include <sys/reboot.h>
+#  include <sys/reboot.h>
 #endif
 
 typedef struct stinfo stinfo;
@@ -253,9 +252,12 @@
     return s[0];
 }
 
-#if !ADB_HOST
 static int create_subprocess(const char *cmd, const char *arg0, const char *arg1)
 {
+#ifdef HAVE_WIN32_PROC
+	fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
+	return -1;
+#else /* !HAVE_WIN32_PROC */
     char *devname;
     int ptm;
     pid_t pid;
@@ -298,6 +300,7 @@
                 cmd, strerror(errno), errno);
         exit(-1);
     } else {
+#if !ADB_HOST
         // set child's OOM adjustment to zero
         char text[64];
         snprintf(text, sizeof text, "/proc/%d/oom_adj", pid);
@@ -308,11 +311,11 @@
         } else {
            D("adb: unable to open %s\n", text);
         }
-
+#endif
         return ptm;
     }
+#endif /* !HAVE_WIN32_PROC */
 }
-#endif /* !ADB_HOST */
 
 #if ADB_HOST
 #define SHELL_COMMAND "/bin/sh"
@@ -320,76 +323,6 @@
 #define SHELL_COMMAND "/system/bin/sh"
 #endif
 
-#if !ADB_HOST
-static void shell_service(int s, void *command)
-{
-    char    buffer[MAX_PAYLOAD];
-    char    buffer2[MAX_PAYLOAD];
-    struct pollfd ufds[2];
-    int     fd, ret = 0;
-    unsigned count = 0;
-    char** args = (char **)command;
-    fd = create_subprocess(SHELL_COMMAND, args[0], args[1]);
-
-    while (1) {
-        while (count < sizeof(buffer)) {
-            ufds[0].fd = fd;
-            ufds[0].events = POLLIN | POLLHUP;
-            ufds[0].revents = 0;
-            ufds[1].fd = s;
-            ufds[1].events = POLLIN | POLLHUP;
-            ufds[1].revents = 0;
-            // use a 100ms timeout so we don't block indefinitely with our
-            // buffer partially filled.
-            ret = poll(ufds, 2, 100);
-            if (ret <= 0) {
-                D("poll returned %d\n", ret);
-                // file has closed or we timed out
-                // set ret to 1 so we don't exit the outer loop
-                ret = 1;
-                break;
-            }
-
-            if (ufds[0].revents & POLLIN) {
-                ret = adb_read(fd, buffer + count, sizeof(buffer) - count);
-                D("read fd ret: %d, count: %d\n", ret, count);
-                if (ret > 0)
-                    count += ret;
-                else
-                    break;
-            }
-            if (ufds[1].revents & POLLIN) {
-                ret = adb_read(s, buffer2, sizeof(buffer2));
-                D("read s ret: %d\n", ret);
-                if (ret > 0)
-                    adb_write(fd, buffer2, ret);
-                else
-                    break;
-            }
-
-            if ((ufds[0].revents & POLLHUP) || (ufds[1].revents & POLLHUP)) {
-                // set flag to exit after flushing the buffer
-                ret = -1;
-                break;
-            }
-        }
-
-        D("writing: %d\n", count);
-        if (count > 0) {
-            adb_write(s, buffer, count);
-            count = 0;
-        }
-        if (ret <= 0)
-            break;
-    }
-
-    D("shell_service done\n");
-
-    adb_close(fd);
-    adb_close(s);
-}
-#endif // !ADB_HOST
-
 int service_to_fd(const char *name)
 {
     int ret = -1;
@@ -440,16 +373,14 @@
         ret = create_jdwp_connection_fd(atoi(name+5));
     } else if (!strncmp(name, "log:", 4)) {
         ret = create_service_thread(log_service, get_log_file_path(name + 4));
+#endif
     } else if(!HOST && !strncmp(name, "shell:", 6)) {
-        const char* args[2];
         if(name[6]) {
-            args[0] = "-c";
-            args[1] = name + 6;
+            ret = create_subprocess(SHELL_COMMAND, "-c", name + 6);
         } else {
-            args[0] = "-";
-            args[1] = 0;
+            ret = create_subprocess(SHELL_COMMAND, "-", 0);
         }
-        ret = create_service_thread(shell_service, (void *)args);
+#if !ADB_HOST
     } else if(!strncmp(name, "sync:", 5)) {
         ret = create_service_thread(file_sync_service, NULL);
     } else if(!strncmp(name, "remount:", 8)) {
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 535361c..c52b992 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -4450,10 +4450,8 @@
                 unary();
                 doPointer();
             } else if (t == '&') {
-                VariableInfo* pVI = VI(tok);
-                pGen->leaR0((int) pVI->pAddress, createPtrType(pVI->pType),
-                        ET_RVALUE);
-                next();
+                unary();
+                doAddressOf();
             } else if (t == EOF ) {
                 error("Unexpected EOF.");
             } else if (t == ';') {
@@ -4529,7 +4527,7 @@
                 pGen->forceR0RVal();
                 Type* pStruct = pGen->getR0Type();
                 if (pStruct->tag == TY_STRUCT) {
-                    doStructMember(pStruct);
+                    doStructMember(pStruct, true);
                 } else {
                     error("expected a struct value to the left of '.'");
                 }
@@ -4538,7 +4536,7 @@
                 Type* pPtr = pGen->getR0Type();
                 if (pPtr->tag == TY_POINTER && pPtr->pHead->tag == TY_STRUCT) {
                     pGen->loadR0FromR0();
-                    doStructMember(pPtr->pHead);
+                    doStructMember(pPtr->pHead, false);
                 } else {
                     error("Expected a pointer to a struct to the left of '->'");
                 }
@@ -4604,7 +4602,7 @@
         }
     }
 
-    void doStructMember(Type* pStruct) {
+    void doStructMember(Type* pStruct, bool isDot) {
         Type* pStructElement = lookupStructMember(pStruct, tok);
         if (pStructElement) {
             next();
@@ -4612,7 +4610,8 @@
         } else {
             String buf;
             decodeToken(buf, tok, true);
-            error("Expected a struct member to the right of '.', got %s", buf.getUnwrapped());
+            error("Expected a struct member to the right of '%s', got %s",
+                    isDot ? "." : "->", buf.getUnwrapped());
         }
     }
 
@@ -4656,6 +4655,16 @@
         }
     }
 
+    void doAddressOf() {
+        Type* pR0 = pGen->getR0Type();
+        bool isFuncPtr = pR0->tag == TY_POINTER && pR0->pHead->tag == TY_FUNC;
+        if ((! isFuncPtr) && pGen->getR0ExpressionType() != ET_LVALUE) {
+            error("Expected an lvalue");
+        }
+        Type* pR0Type = pGen->getR0Type();
+        pGen->setR0ExpressionType(ET_RVALUE);
+    }
+
     /* Recursive descent parser for binary operations.
      */
     void binaryOp(int level) {
@@ -5293,7 +5302,7 @@
 
     void checkLVal() {
         if (pGen->getR0ExpressionType() != ET_LVALUE) {
-            error("Expected an lval");
+            error("Expected an lvalue");
         }
     }
 
diff --git a/libacc/tests/data/addressOf.c b/libacc/tests/data/addressOf.c
new file mode 100644
index 0000000..e7acde5
--- /dev/null
+++ b/libacc/tests/data/addressOf.c
@@ -0,0 +1,31 @@
+void testStruct() {
+    struct str {
+        float x;
+        float y;
+    };
+
+    struct str base;
+    int index = 0;
+
+    base.x = 10.0;
+    struct str *s = &base;
+
+    float *v = &(*s).x;
+    float *v2 = &s[index].x;
+    printf("testStruct: %g %g %g\n",base.x, *v, *v2);
+}
+
+void testArray() {
+    int a[2];
+    a[0] = 1;
+    a[1] = 2;
+    int* p = &a[0];
+    int* p2 = a;
+    printf("testArray: %d %d %d\n", a[0], *p, *p2);
+}
+
+int main() {
+    testStruct();
+    testArray();
+    return 0;
+}
diff --git a/libacc/tests/test.py b/libacc/tests/test.py
index a8575b1..c982d16 100644
--- a/libacc/tests/test.py
+++ b/libacc/tests/test.py
@@ -471,6 +471,13 @@
 result: 6
 ""","""""")
 
+    def testAddressOf(self):
+        self.compileCheck(["-R", "data/addressOf.c"], """Executing compiled code:
+testStruct: 10 10 10
+testArray: 1 1 1
+result: 0
+""","""""")
+
 def main():
     checkEnvironment()
     parseArgv()
diff --git a/logcat/event-log-tags b/logcat/event-log-tags
index b5386d3..4db86cb 100644
--- a/logcat/event-log-tags
+++ b/logcat/event-log-tags
@@ -82,6 +82,10 @@
 # disk space free on the /data partition in bytes
 2746 free_storage_left (data|2|2)
 
+# contacts aggregation: time and number of contacts.
+# count is negative for query phase, positive for merge phase
+2747 contacts_aggregation (aggregation time|2|3), (count|1|1)
+
 # when a NotificationManager.notify is called
 2750 notification_enqueue (pkg|3),(id|1|5),(notification|3)
 # when someone tries to cancel a notification, the notification manager sometimes