Implement data push from scripts.  Fixes the problem where apps would have to poll to monitor a scripts state.
Fix bug in StoreState where state could be overridden by the default unless the script used more than one state.

Change only impacts renderscript and renderscript apps.
diff --git a/RenderScript.h b/RenderScript.h
index 87a2f4a..9b04393 100644
--- a/RenderScript.h
+++ b/RenderScript.h
@@ -59,6 +59,10 @@
 void rsContextDestroy(RsContext);
 void rsObjDestroyOOB(RsContext, void *);
 
+uint32_t rsContextGetMessage(RsContext, void *data, size_t *receiveLen, size_t bufferLen, bool wait);
+void rsContextInitToClient(RsContext);
+void rsContextDeinitToClient(RsContext);
+
 #define RS_MAX_TEXTURE 2
 
 enum RsDataType {
diff --git a/rsContext.cpp b/rsContext.cpp
index 169d5d4..a1e9e45 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -142,6 +142,7 @@
     if (this->props.mLogTimes) {
         timerSet(RS_TIMER_SCRIPT);
     }
+    mStateFragmentStore.mLast.clear();
     bool ret = runScript(mRootScript.get(), 0);
     return ret;
 }
@@ -529,6 +530,64 @@
     }
 }
 
+uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait)
+{
+    //LOGE("getMessageToClient %i %i", bufferLen, wait);
+    if (!wait) {
+        if (mIO.mToClient.isEmpty()) {
+            // No message to get and not going to wait for one.
+            receiveLen = 0;
+            return 0;
+        }
+    }
+
+    //LOGE("getMessageToClient 2 con=%p", this);
+    uint32_t bytesData = 0;
+    uint32_t commandID = 0;
+    const void *d = mIO.mToClient.get(&commandID, &bytesData);
+    //LOGE("getMessageToClient 3    %i  %i", commandID, bytesData);
+
+    *receiveLen = bytesData;
+    if (bufferLen >= bytesData) {
+        memcpy(data, d, bytesData);
+        mIO.mToClient.next();
+        return commandID;
+    }
+    return 0;
+}
+
+bool Context::sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace)
+{
+    //LOGE("sendMessageToClient %i %i %i", cmdID, len, waitForSpace);
+    if (cmdID == 0) {
+        LOGE("Attempting to send invalid command 0 to client.");
+        return false;
+    }
+    if (!waitForSpace) {
+        if (mIO.mToClient.getFreeSpace() < len) {
+            // Not enough room, and not waiting.
+            return false;
+        }
+    }
+    //LOGE("sendMessageToClient 2");
+    void *p = mIO.mToClient.reserve(len);
+    memcpy(p, data, len);
+    mIO.mToClient.commit(cmdID, len);
+    //LOGE("sendMessageToClient 3");
+    return true;
+}
+
+void Context::initToClient()
+{
+    while(!mRunning) {
+        usleep(100);
+    }
+}
+
+void Context::deinitToClient()
+{
+    mIO.mToClient.shutdown();
+}
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////
@@ -636,3 +695,21 @@
     rsc->objDestroyAdd(static_cast<ObjectBase *>(obj));
 }
 
+uint32_t rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, size_t bufferLen, bool wait)
+{
+    Context * rsc = static_cast<Context *>(vrsc);
+    return rsc->getMessageToClient(data, receiveLen, bufferLen, wait);
+}
+
+void rsContextInitToClient(RsContext vrsc)
+{
+    Context * rsc = static_cast<Context *>(vrsc);
+    rsc->initToClient();
+}
+
+void rsContextDeinitToClient(RsContext vrsc)
+{
+    Context * rsc = static_cast<Context *>(vrsc);
+    rsc->deinitToClient();
+}
+
diff --git a/rsContext.h b/rsContext.h
index cef421d..b56e7d7 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -97,6 +97,12 @@
     void appendNameDefines(String8 *str) const;
     void appendVarDefines(String8 *str) const;
 
+    uint32_t getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait);
+    bool sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace);
+
+    void initToClient();
+    void deinitToClient();
+
     ProgramFragment * getDefaultProgramFragment() const {
         return mStateFragment.mDefault.get();
     }
diff --git a/rsLocklessFifo.cpp b/rsLocklessFifo.cpp
index b0540a6..085a81e 100644
--- a/rsLocklessFifo.cpp
+++ b/rsLocklessFifo.cpp
@@ -99,6 +99,9 @@
 
 void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes)
 {
+    if (mInShutdown) {
+        return;
+    }
     //dumpState("commit 1");
     reinterpret_cast<uint16_t *>(mPut)[0] = command;
     reinterpret_cast<uint16_t *>(mPut)[1] = sizeInBytes;
@@ -109,6 +112,9 @@
 
 void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes)
 {
+    if (mInShutdown) {
+        return;
+    }
     commit(command, sizeInBytes);
     flush();
 }
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index 17d14f5..9a96290 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -1002,6 +1002,12 @@
     return rs888to565(ir, ig, ib);
 }
 
+static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace)
+{
+    GET_TLS();
+    return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0);
+}
+
 //////////////////////////////////////////////////////////////////////////////
 // Class implementation
 //////////////////////////////////////////////////////////////////////////////
@@ -1270,6 +1276,8 @@
     { "getHeight", (void *)&SC_getHeight,
         "int", "()" },
 
+    { "sendToClient", (void *)&SC_toClient,
+        "int", "(void *data, int cmdID, int len, int waitForSpace)" },
 
 
     { "debugF", (void *)&SC_debugF,
diff --git a/rsThreadIO.cpp b/rsThreadIO.cpp
index 4d3d73a..527b3d7 100644
--- a/rsThreadIO.cpp
+++ b/rsThreadIO.cpp
@@ -24,6 +24,7 @@
 ThreadIO::ThreadIO()
 {
     mToCore.init(16 * 1024);
+    mToClient.init(1024);
 }
 
 ThreadIO::~ThreadIO()
diff --git a/rsThreadIO.h b/rsThreadIO.h
index 1f6a0c2..95270f5 100644
--- a/rsThreadIO.h
+++ b/rsThreadIO.h
@@ -39,7 +39,7 @@
 
 
     LocklessCommandFifo mToCore;
-    //LocklessCommandFifo mToClient;
+    LocklessCommandFifo mToClient;
 
     intptr_t mToCoreRet;