am b85c2494: am 03b87b49: Merge "Make host ashmem_create_region seed only once."

* commit 'b85c2494df1e1003b3101e36b29faace3a51dc3f':
  Make host ashmem_create_region seed only once.
diff --git a/libcutils/ashmem-host.c b/libcutils/ashmem-host.c
index 7873964..4ac4f57 100644
--- a/libcutils/ashmem-host.c
+++ b/libcutils/ashmem-host.c
@@ -22,6 +22,8 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <pthread.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -36,83 +38,83 @@
 #define __unused __attribute__((__unused__))
 #endif
 
+static pthread_once_t seed_initialized = PTHREAD_ONCE_INIT;
+static void initialize_random() {
+    srand(time(NULL) + getpid());
+}
+
 int ashmem_create_region(const char *ignored __unused, size_t size)
 {
-	static const char txt[] = "abcdefghijklmnopqrstuvwxyz"
-				  "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-	char name[64];
-	unsigned int retries = 0;
-	pid_t pid = getpid();
-	int fd;
+    static const char txt[] = "abcdefghijklmnopqrstuvwxyz"
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    char name[64];
+    unsigned int retries = 0;
+    pid_t pid = getpid();
+    int fd;
+    if (pthread_once(&seed_initialized, &initialize_random) != 0) {
+        return -1;
+    }
+    do {
+        /* not beautiful, its just wolf-like loop unrolling */
+        snprintf(name, sizeof(name), "/tmp/android-ashmem-%d-%c%c%c%c%c%c%c%c",
+        pid,
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))]);
 
-	srand(time(NULL) + pid);
-
-retry:
-	/* not beautiful, its just wolf-like loop unrolling */
-	snprintf(name, sizeof(name), "/tmp/android-ashmem-%d-%c%c%c%c%c%c%c%c",
-		pid,
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))]);
-
-	/* open O_EXCL & O_CREAT: we are either the sole owner or we fail */
-	fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
-	if (fd == -1) {
-		/* unlikely, but if we failed because `name' exists, retry */
-		if (errno == EEXIST && ++retries < 6)
-			goto retry;
-		return -1;
-	}
-
-	/* truncate the file to `len' bytes */
-	if (ftruncate(fd, size) == -1)
-		goto error;
-
-	if (unlink(name) == -1)
-		goto error;
-
-	return fd;
-error:
-	close(fd);
-	return -1;
+        /* open O_EXCL & O_CREAT: we are either the sole owner or we fail */
+        fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
+        if (fd == -1) {
+            /* unlikely, but if we failed because `name' exists, retry */
+            if (errno != EEXIST || ++retries >= 6) {
+                return -1;
+            }
+        }
+    } while (fd == -1);
+    /* truncate the file to `len' bytes */
+    if (ftruncate(fd, size) != -1 && unlink(name) != -1) {
+        return fd;
+    }
+    close(fd);
+    return -1;
 }
 
 int ashmem_set_prot_region(int fd __unused, int prot __unused)
 {
-	return 0;
+    return 0;
 }
 
 int ashmem_pin_region(int fd __unused, size_t offset __unused, size_t len __unused)
 {
-	return ASHMEM_NOT_PURGED;
+    return ASHMEM_NOT_PURGED;
 }
 
 int ashmem_unpin_region(int fd __unused, size_t offset __unused, size_t len __unused)
 {
-	return ASHMEM_IS_UNPINNED;
+    return ASHMEM_IS_UNPINNED;
 }
 
 int ashmem_get_size_region(int fd)
 {
-        struct stat buf;
-        int result;
+    struct stat buf;
+    int result;
 
-        result = fstat(fd, &buf);
-        if (result == -1) {
-                return -1;
-        }
+    result = fstat(fd, &buf);
+    if (result == -1) {
+        return -1;
+    }
 
-        // Check if this is an "ashmem" region.
-        // TODO: This is very hacky, and can easily break. We need some reliable indicator.
-        if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) {
-                errno = ENOTTY;
-                return -1;
-        }
+    // Check if this is an "ashmem" region.
+    // TODO: This is very hacky, and can easily break. We need some reliable indicator.
+    if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) {
+        errno = ENOTTY;
+        return -1;
+    }
 
-        return (int)buf.st_size;  // TODO: care about overflow (> 2GB file)?
+    return (int)buf.st_size;    // TODO: care about overflow (> 2GB file)?
 }