auto import from //depot/cupcake/@135843
diff --git a/simulator/app/Semaphore.cpp b/simulator/app/Semaphore.cpp
new file mode 100644
index 0000000..3b6ee7b
--- /dev/null
+++ b/simulator/app/Semaphore.cpp
@@ -0,0 +1,516 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+// Inter-process semaphores.
+//
+#include "Semaphore.h"
+
+#if defined(HAVE_MACOSX_IPC)
+# include <semaphore.h>
+#elif defined(HAVE_SYSV_IPC)
+# include <sys/types.h>
+# include <sys/ipc.h>
+# include <sys/sem.h>
+#elif defined(HAVE_WIN32_IPC)
+# include <windows.h>
+#elif defined(HAVE_ANDROID_IPC)
+// not yet
+#else
+# error "unknown sem config"
+#endif
+
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+
+#if defined(HAVE_ANDROID_IPC) // ----------------------------------------------
+
+Semaphore::Semaphore(void)
+ : mHandle(0), mCreator(false), mKey(-1)
+{}
+
+Semaphore::~Semaphore(void)
+{}
+
+bool Semaphore::create(int key, int initialValue, bool deleteExisting)
+{
+ return false;
+}
+
+bool Semaphore::attach(int key)
+{
+ return false;
+}
+
+void Semaphore::acquire(void)
+{}
+
+void Semaphore::release(void)
+{}
+
+bool Semaphore::tryAcquire(void)
+{
+ return false;
+}
+
+#elif defined(HAVE_MACOSX_IPC) // ---------------------------------------------
+
+/*
+ * The SysV semaphores don't work on all of our machines. The POSIX
+ * named semaphores seem to work better.
+ */
+
+#define kInvalidHandle SEM_FAILED
+
+static const char* kSemStr = "/tmp/android-sem-";
+
+/*
+ * Constructor. Just init fields.
+ */
+Semaphore::Semaphore(void)
+ : mHandle((unsigned long) kInvalidHandle), mCreator(false), mKey(-1)
+{
+}
+
+/*
+ * Destructor. If we created the semaphore, destroy it.
+ */
+Semaphore::~Semaphore(void)
+{
+ LOG(LOG_VERBOSE, "sem", "~Semaphore(handle=%ld creator=%d)\n",
+ mHandle, mCreator);
+
+ if (mHandle != (unsigned long) kInvalidHandle) {
+ sem_close((sem_t*) mHandle);
+
+ if (mCreator) {
+ char nameBuf[64];
+ int cc;
+
+ snprintf(nameBuf, sizeof(nameBuf), "%s%d", kSemStr, mKey);
+
+ cc = sem_unlink(nameBuf);
+ if (cc != 0) {
+ LOG(LOG_ERROR, "sem",
+ "Failed to remove sem '%s' (errno=%d)\n", nameBuf, errno);
+ }
+ }
+ }
+}
+
+/*
+ * Create the semaphore.
+ */
+bool Semaphore::create(int key, int initialValue, bool deleteExisting)
+{
+ int cc;
+ char nameBuf[64];
+
+ snprintf(nameBuf, sizeof(nameBuf), "%s%d", kSemStr, key);
+
+ if (deleteExisting) {
+ cc = sem_unlink(nameBuf);
+ if (cc != 0 && errno != ENOENT) {
+ LOG(LOG_WARN, "sem", "Warning: failed to remove sem '%s'\n",
+ nameBuf);
+ /* keep going? */
+ }
+ }
+
+ /* create and set initial value */
+ sem_t* semPtr;
+ semPtr = sem_open(nameBuf, O_CREAT | O_EXCL, 0666, 1);
+ if (semPtr == (sem_t*)SEM_FAILED) {
+ LOG(LOG_ERROR, "sem",
+ "ERROR: sem_open failed to create '%s' (errno=%d)\n",
+ nameBuf, errno);
+ return false;
+ }
+
+ mHandle = (unsigned long) semPtr;
+ mCreator = true;
+ mKey = key;
+
+ return true;
+}
+
+/*
+ * Attach to an existing semaphore.
+ */
+bool Semaphore::attach(int key)
+{
+ char nameBuf[64];
+
+ snprintf(nameBuf, sizeof(nameBuf), "%s%d", kSemStr, key);
+
+ sem_t* semPtr;
+ semPtr = sem_open(nameBuf, 0, 0666, 0);
+ if (semPtr == (sem_t*) SEM_FAILED) {
+ LOG(LOG_ERROR, "sem",
+ "ERROR: sem_open failed to attach to '%s' (errno=%d)\n",
+ nameBuf, errno);
+ return false;
+ }
+
+ mHandle = (unsigned long) semPtr;
+ assert(mCreator == false);
+ mKey = key;
+
+ return true;
+}
+
+/*
+ * Acquire or release the semaphore.
+ */
+void Semaphore::acquire(void)
+{
+ int cc = sem_wait((sem_t*) mHandle);
+ if (cc != 0)
+ LOG(LOG_WARN, "sem", "acquire failed (errno=%d)\n", errno);
+}
+void Semaphore::release(void)
+{
+ int cc = sem_post((sem_t*) mHandle);
+ if (cc != 0)
+ LOG(LOG_WARN, "sem", "release failed (errno=%d)\n", errno);
+}
+bool Semaphore::tryAcquire(void)
+{
+ int cc = sem_trywait((sem_t*) mHandle);
+ if (cc != 0) {
+ if (errno != EAGAIN)
+ LOG(LOG_WARN, "sem", "tryAcquire failed (errno=%d)\n", errno);
+ return false;
+ }
+ return true;
+}
+
+
+#elif defined(HAVE_SYSV_IPC) // -----------------------------------------------
+
+/*
+ * Basic SysV semaphore stuff.
+ */
+
+#define kInvalidHandle ((unsigned long)-1)
+
+#if defined(_SEM_SEMUN_UNDEFINED)
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
+ unsigned short *array; /* array for GETALL, SETALL */
+ /* Linux specific part: */
+ struct seminfo *__buf; /* buffer for IPC_INFO */
+};
+#endif
+
+/*
+ * Constructor. Just init fields.
+ */
+Semaphore::Semaphore(void)
+ : mHandle(kInvalidHandle), mCreator(false)
+{
+}
+
+/*
+ * Destructor. If we created the semaphore, destroy it.
+ */
+Semaphore::~Semaphore(void)
+{
+ LOG(LOG_VERBOSE, "sem", "~Semaphore(handle=%ld creator=%d)\n",
+ mHandle, mCreator);
+
+ if (mCreator && mHandle != kInvalidHandle) {
+ int cc;
+
+ cc = semctl((int) mHandle, 0, IPC_RMID);
+ if (cc != 0) {
+ LOG(LOG_WARN, "sem",
+ "Destructor failed to destroy key=%ld\n", mHandle);
+ }
+ }
+}
+
+/*
+ * Create the semaphore.
+ */
+bool Semaphore::create(int key, int initialValue, bool deleteExisting)
+{
+ int semid, cc;
+
+ if (deleteExisting) {
+ semid = semget(key, 1, 0);
+ if (semid != -1) {
+ LOG(LOG_DEBUG, "sem", "Key %d exists (semid=%d), removing\n",
+ key, semid);
+ cc = semctl(semid, 0, IPC_RMID);
+ if (cc != 0) {
+ LOG(LOG_ERROR, "sem", "Failed to remove key=%d semid=%d\n",
+ key, semid);
+ return false;
+ } else {
+ LOG(LOG_DEBUG, "sem",
+ "Removed previous semaphore with key=%d\n", key);
+ }
+ }
+ }
+
+ semid = semget(key, 1, 0600 | IPC_CREAT | IPC_EXCL);
+ if (semid == -1) {
+ LOG(LOG_ERROR, "sem", "Failed to create key=%d (errno=%d)\n",
+ key, errno);
+ return false;
+ }
+
+ mHandle = semid;
+ mCreator = true;
+ mKey = key;
+
+ /*
+ * Set initial value.
+ */
+ union semun init;
+ init.val = initialValue;
+ cc = semctl(semid, 0, SETVAL, init);
+ if (cc == -1) {
+ LOG(LOG_ERROR, "sem",
+ "Unable to initialize semaphore, key=%d iv=%d (errno=%d)\n",
+ key, initialValue, errno);
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Attach to an existing semaphore.
+ */
+bool Semaphore::attach(int key)
+{
+ int semid;
+
+ semid = semget(key, 0, 0);
+ if (semid == -1) {
+ LOG(LOG_ERROR, "sem", "Failed to find key=%d\n", key);
+ return false;
+ }
+
+ mHandle = semid;
+ assert(mCreator == false);
+ mKey = key;
+
+ return true;
+}
+
+/*
+ * Acquire or release the semaphore.
+ */
+void Semaphore::acquire(void)
+{
+ assert(mHandle != kInvalidHandle);
+ adjust(-1, true);
+}
+void Semaphore::release(void)
+{
+ assert(mHandle != kInvalidHandle);
+ adjust(1, true);
+}
+bool Semaphore::tryAcquire(void)
+{
+ assert(mHandle != kInvalidHandle);
+ return adjust(-1, false);
+}
+
+/*
+ * Do the actual semaphore manipulation.
+ *
+ * The semaphore's value indicates the number of free resources. Pass
+ * in a negative value for "adj" to acquire resources, or a positive
+ * value to free resources.
+ *
+ * Returns true on success, false on failure.
+ */
+bool Semaphore::adjust(int adj, bool wait)
+{
+ struct sembuf op;
+ int cc;
+
+ op.sem_num = 0;
+ op.sem_op = adj;
+ op.sem_flg = SEM_UNDO;
+ if (!wait)
+ op.sem_flg |= IPC_NOWAIT;
+
+ cc = semop((int) mHandle, &op, 1);
+ if (cc != 0) {
+ if (wait || errno != EAGAIN) {
+ LOG(LOG_WARN, "sem",
+ "semaphore adjust by %d failed for semid=%ld (errno=%d)\n",
+ adj, mHandle, errno);
+ }
+ return false;
+ }
+
+ //LOG(LOG_VERBOSE, "sem",
+ // "adjusted semaphore by %d (semid=%ld)\n", adj, mHandle);
+
+ return true;
+}
+
+
+#elif defined(HAVE_WIN32_IPC) // ----------------------------------------------
+
+/*
+ * Win32 semaphore implementation.
+ *
+ * Pretty straightforward.
+ */
+
+static const char* kSemStr = "android-sem-";
+
+/*
+ * Constructor. Just init fields.
+ */
+Semaphore::Semaphore(void)
+ : mHandle((unsigned long) INVALID_HANDLE_VALUE), mCreator(false)
+{
+}
+
+/*
+ * Destructor. Just close the semaphore handle.
+ */
+Semaphore::~Semaphore(void)
+{
+ LOG(LOG_DEBUG, "sem", "~Semaphore(handle=%ld creator=%d)\n",
+ mHandle, mCreator);
+
+ if (mHandle != (unsigned long) INVALID_HANDLE_VALUE)
+ CloseHandle((HANDLE) mHandle);
+}
+
+/*
+ * Create the semaphore.
+ */
+bool Semaphore::create(int key, int initialValue, bool deleteExisting)
+{
+ char keyBuf[64];
+ HANDLE hSem;
+ long max;
+
+ snprintf(keyBuf, sizeof(keyBuf), "%s%d", kSemStr, key);
+
+ if (initialValue == 0)
+ max = 1;
+ else
+ max = initialValue;
+
+ hSem = CreateSemaphore(
+ NULL, // security attributes
+ initialValue, // initial count
+ max, // max count, must be >= initial
+ keyBuf); // object name
+ if (hSem == NULL) {
+ DWORD err = GetLastError();
+ if (err == ERROR_ALREADY_EXISTS) {
+ LOG(LOG_ERROR, "sem", "Semaphore '%s' already exists\n", keyBuf);
+ } else {
+ LOG(LOG_ERROR, "sem", "CreateSemaphore(%s) failed (err=%ld)\n",
+ keyBuf, err);
+ }
+ return false;
+ }
+
+ mHandle = (unsigned long) hSem;
+ mCreator = true;
+ mKey = key;
+
+ //LOG(LOG_DEBUG, "sem", "Semaphore '%s' created (handle=0x%08lx)\n",
+ // keyBuf, mHandle);
+
+ return true;
+}
+
+/*
+ * Attach to an existing semaphore.
+ */
+bool Semaphore::attach(int key)
+{
+ char keyBuf[64];
+ HANDLE hSem;
+
+ snprintf(keyBuf, sizeof(keyBuf), "%s%d", kSemStr, key);
+
+ hSem = OpenSemaphore(
+ //SEMAPHORE_MODIFY_STATE, // mostly-full access
+ SEMAPHORE_ALL_ACCESS, // full access
+ FALSE, // don't let kids inherit handle
+ keyBuf); // object name
+ if (hSem == NULL) {
+ LOG(LOG_ERROR, "sem", "OpenSemaphore(%s) failed (err=%ld)\n",
+ keyBuf, GetLastError());
+ return false;
+ }
+
+ mHandle = (unsigned long) hSem;
+ assert(mCreator == false);
+ mKey = key;
+
+ return true;
+}
+
+/*
+ * Acquire or release the semaphore.
+ */
+void Semaphore::acquire(void)
+{
+ DWORD result;
+
+ assert(mHandle != (unsigned long) INVALID_HANDLE_VALUE);
+
+ result = WaitForSingleObject((HANDLE) mHandle, INFINITE);
+ if (result != WAIT_OBJECT_0) {
+ LOG(LOG_WARN, "sem",
+ "WaitForSingleObject(INF) on semaphore returned %ld (err=%ld)\n",
+ result, GetLastError());
+ }
+}
+void Semaphore::release(void)
+{
+ DWORD result;
+
+ assert(mHandle != (unsigned long) INVALID_HANDLE_VALUE);
+
+ result = ReleaseSemaphore((HANDLE) mHandle, 1, NULL); // incr by 1
+ if (result == 0) {
+ LOG(LOG_WARN, "sem", "ReleaseSemaphore failed (err=%ld)\n",
+ GetLastError());
+ }
+}
+bool Semaphore::tryAcquire(void)
+{
+ DWORD result;
+
+ assert(mHandle != (unsigned long) INVALID_HANDLE_VALUE);
+ result = WaitForSingleObject((HANDLE) mHandle, 0);
+ if (result == WAIT_OBJECT_0)
+ return true; // grabbed it
+ else if (result == WAIT_TIMEOUT)
+ return false; // not available
+ else if (result == WAIT_FAILED) {
+ LOG(LOG_WARN, "sem", "WaitForSingleObject(0) on sem failed (err=%ld)\n",
+ GetLastError());
+ return false;
+ } else {
+ LOG(LOG_WARN, "sem",
+ "WaitForSingleObject(0) on sem returned %ld (err=%ld)\n",
+ result, GetLastError());
+ return false;
+ }
+}
+
+#endif // ---------------------------------------------------------------------