Replace spins with proper pthread conditions.
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 7248ecc..2a5f65d 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -130,14 +130,10 @@
      rsc->mRunning = true;
      bool mDraw = true;
      while (!rsc->mExit) {
-         mDraw |= gIO->playCoreCommands(rsc);
+         mDraw |= gIO->playCoreCommands(rsc, !mDraw);
+         mDraw &= (rsc->mRootScript.get() != NULL);
 
-         if (!mDraw || !rsc->mRootScript.get()) {
-             usleep(10000);
-             continue;
-         }
-
-         if (rsc->mRootScript.get()) {
+         if (mDraw) {
              mDraw = rsc->runRootScript();
              eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
          }
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
index 67ab434..37ec14b 100644
--- a/libs/rs/rsLocklessFifo.cpp
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -37,16 +37,8 @@
         return false;
     }
 
-    int status = pthread_mutex_init(&mMutex, NULL);
-    if (status) {
-        LOGE("LocklessFifo mutex init failure");
-        free(mBuffer);
-        return false;
-    }
-    status = pthread_cond_init(&mCondition, NULL);
-    if (status) {
-        LOGE("LocklessFifo condition init failure");
-        pthread_mutex_destroy(&mMutex);
+    if (!mSignalToControl.init() || !mSignalToWorker.init()) {
+        LOGE("Signal setup failed");
         free(mBuffer);
         return false;
     }
@@ -106,6 +98,7 @@
     mPut += ((sizeInBytes + 3) & ~3) + 4;
     //dumpState("commit 2");
 
+    mSignalToWorker.set();
 }
 
 void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes)
@@ -118,7 +111,7 @@
 {
     //dumpState("flush 1");
     while(mPut != mGet) {
-        usleep(1);
+        mSignalToControl.wait();
     }
     //dumpState("flush 2");
 }
@@ -126,8 +119,10 @@
 const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData)
 {
     while(1) {
+        //dumpState("get");
         while(isEmpty()) {
-            usleep(10);
+            mSignalToControl.set();
+            mSignalToWorker.wait();
         }
         //dumpState("get 3");
 
@@ -149,6 +144,9 @@
 {
     uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1];
     mGet += ((bytes + 3) & ~3) + 4;
+    if (isEmpty()) {
+        mSignalToControl.set();
+    }
     //dumpState("next");
 }
 
@@ -179,4 +177,79 @@
     LOGE("%s  put %p, get %p,  buf %p,  end %p", s, mPut, mGet, mBuffer, mEnd);
 }
 
+LocklessCommandFifo::Signal::Signal()
+{
+    mSet = true;
+}
+
+LocklessCommandFifo::Signal::~Signal()
+{
+    pthread_mutex_destroy(&mMutex);
+    pthread_cond_destroy(&mCondition);
+}
+
+bool LocklessCommandFifo::Signal::init()
+{
+    int status = pthread_mutex_init(&mMutex, NULL);
+    if (status) {
+        LOGE("LocklessFifo mutex init failure");
+        return false;
+    }
+
+    status = pthread_cond_init(&mCondition, NULL);
+    if (status) {
+        LOGE("LocklessFifo condition init failure");
+        pthread_mutex_destroy(&mMutex);
+        return false;
+    }
+
+    return true;
+}
+
+void LocklessCommandFifo::Signal::set()
+{
+    int status;
+
+    status = pthread_mutex_lock(&mMutex);
+    if (status) {
+        LOGE("LocklessCommandFifo: error %i locking for set condition.", status);
+        return;
+    }
+
+    mSet = true;
+
+    status = pthread_cond_signal(&mCondition);
+    if (status) {
+        LOGE("LocklessCommandFifo: error %i on set condition.", status);
+    }
+
+    status = pthread_mutex_unlock(&mMutex);
+    if (status) {
+        LOGE("LocklessCommandFifo: error %i unlocking for set condition.", status);
+    }
+}
+
+void LocklessCommandFifo::Signal::wait()
+{
+    int status;
+
+    status = pthread_mutex_lock(&mMutex);
+    if (status) {
+        LOGE("LocklessCommandFifo: error %i locking for condition.", status);
+        return;
+    }
+
+    if (!mSet) {
+        status = pthread_cond_wait(&mCondition, &mMutex);
+        if (status) {
+            LOGE("LocklessCommandFifo: error %i waiting on condition.", status);
+        }
+    }
+    mSet = false;
+
+    status = pthread_mutex_unlock(&mMutex);
+    if (status) {
+        LOGE("LocklessCommandFifo: error %i unlocking for condition.", status);
+    }
+}
 
diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h
index ddef382..2f4d5c5 100644
--- a/libs/rs/rsLocklessFifo.h
+++ b/libs/rs/rsLocklessFifo.h
@@ -41,14 +41,32 @@
 
 
 protected:
+    class Signal {
+    public:
+        Signal();
+        ~Signal();
+
+        bool init();
+
+        void set();
+        void wait();
+
+    protected:
+        bool mSet;
+        pthread_mutex_t mMutex;
+        pthread_cond_t mCondition;
+    };
+
     uint8_t * volatile mPut;
     uint8_t * volatile mGet;
     uint8_t * mBuffer;
     uint8_t * mEnd;
     uint8_t mSize;
 
-    pthread_mutex_t mMutex;
-    pthread_cond_t mCondition;
+    Signal mSignalToWorker;
+    Signal mSignalToControl;
+
+
 
 public:
     void * reserve(uint32_t bytes);
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 23c808a..5641581 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -34,16 +34,17 @@
 {
 }
 
-bool ThreadIO::playCoreCommands(Context *con)
+bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand)
 {
     //LOGE("playCoreCommands 1");
     uint32_t cmdID = 0;
     uint32_t cmdSize = 0;
     bool ret = false;
-    while(!mToCore.isEmpty()) {
+    while(!mToCore.isEmpty() || waitForCommand) {
         ret = true;
         //LOGE("playCoreCommands 2");
         const void * data = mToCore.get(&cmdID, &cmdSize);
+        waitForCommand = false;
         //LOGE("playCoreCommands 3 %i %i", cmdID, cmdSize);
 
         gPlaybackFuncs[cmdID](con, data);
diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h
index ae2ffc0..973ee05 100644
--- a/libs/rs/rsThreadIO.h
+++ b/libs/rs/rsThreadIO.h
@@ -37,7 +37,7 @@
 
     // Plays back commands from the client.
     // Returns true if any commands were processed.
-    bool playCoreCommands(Context *con);
+    bool playCoreCommands(Context *con, bool waitForCommand);
 
 
     LocklessCommandFifo mToCore;