Improve renderscript context teardown.  Track object in the system and then force their cleanup by releasing all user references once destroy context is called.  Java layer will no longer send destroy notifications for objects garbage collected once a context is destroyed.
diff --git a/rsObjectBase.cpp b/rsObjectBase.cpp
index 7e7afab..acfc5ce 100644
--- a/rsObjectBase.cpp
+++ b/rsObjectBase.cpp
@@ -15,22 +15,39 @@
  */
 
 #include "rsObjectBase.h"
+#include "rsContext.h"
 
 using namespace android;
 using namespace android::renderscript;
 
-ObjectBase::ObjectBase()
+ObjectBase::ObjectBase(Context *rsc)
 {
     mUserRefCount = 0;
     mSysRefCount = 0;
     mName = NULL;
+    mRSC = NULL;
+    mNext = NULL;
+    mPrev = NULL;
+    setContext(rsc);
 }
 
 ObjectBase::~ObjectBase()
 {
-    //LOGV("~ObjectBase %p  ref %i", this, mRefCount);
+    //LOGV("~ObjectBase %p  ref %i,%i", this, mUserRefCount, mSysRefCount);
     rsAssert(!mUserRefCount);
     rsAssert(!mSysRefCount);
+    remove();
+}
+
+void ObjectBase::setContext(Context *rsc)
+{
+    if (mRSC) {
+        remove();
+    }
+    mRSC = rsc;
+    if (rsc) {
+        add();
+    }
 }
 
 void ObjectBase::incUserRef() const
@@ -45,34 +62,41 @@
     //LOGV("ObjectBase %p inc ref %i", this, mRefCount);
 }
 
-void ObjectBase::decUserRef() const
+bool ObjectBase::checkDelete() const
+{
+    if (!(mSysRefCount | mUserRefCount)) {
+        if (mName) {
+            LOGV("Deleting RS object %p, name %s", this, mName);
+        } else {
+            LOGV("Deleting RS object %p, no name", this);
+        }
+        delete this;
+        return true;
+    }
+    return false;
+}
+
+bool ObjectBase::decUserRef() const
 {
     rsAssert(mUserRefCount > 0);
     mUserRefCount --;
     //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
-    if (!(mSysRefCount | mUserRefCount)) {
-        if (mName) {
-            LOGV("Deleting RS object %p, name %s", this, mName);
-        } else {
-            LOGV("Deleting RS object %p, no name", this);
-        }
-        delete this;
-    }
+    return checkDelete();
 }
 
-void ObjectBase::decSysRef() const
+bool ObjectBase::zeroUserRef() const
+{
+    mUserRefCount = 0;
+    //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
+    return checkDelete();
+}
+
+bool ObjectBase::decSysRef() const
 {
     rsAssert(mSysRefCount > 0);
     mSysRefCount --;
     //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
-    if (!(mSysRefCount | mUserRefCount)) {
-        if (mName) {
-            LOGV("Deleting RS object %p, name %s", this, mName);
-        } else {
-            LOGV("Deleting RS object %p, no name", this);
-        }
-        delete this;
-    }
+    return checkDelete();
 }
 
 void ObjectBase::setName(const char *name)
@@ -96,3 +120,55 @@
     }
 }
 
+void ObjectBase::add() const
+{
+    rsAssert(!mNext);
+    rsAssert(!mPrev);
+    //LOGV("calling add  rsc %p", mRSC);
+    mNext = mRSC->mObjHead;
+    if (mRSC->mObjHead) {
+        mRSC->mObjHead->mPrev = this;
+    }
+    mRSC->mObjHead = this;
+}
+
+void ObjectBase::remove() const
+{
+    //LOGV("calling remove  rsc %p", mRSC);
+    if (!mRSC) {
+        rsAssert(!mPrev);
+        rsAssert(!mNext);
+        return;
+    }
+    if (mRSC->mObjHead == this) {
+        mRSC->mObjHead = mNext;
+    }
+    if (mPrev) {
+        mPrev->mNext = mNext;
+    }
+    if (mNext) {
+        mNext->mPrev = mPrev;
+    }
+    mPrev = NULL;
+    mNext = NULL;
+}
+
+void ObjectBase::zeroAllUserRef(Context *rsc)
+{
+    LOGV("Forcing release of all outstanding user refs.");
+
+    // This operation can be slow, only to be called during context cleanup.
+    const ObjectBase * o = rsc->mObjHead;
+    while (o) {
+        //LOGE("o %p", o);
+        if (o->zeroUserRef()) {
+            // deleted the object and possibly others, restart from head.
+            o = rsc->mObjHead;
+            //LOGE("o head %p", o);
+        } else {
+            o = o->mNext;
+            //LOGE("o next %p", o);
+        }
+    }
+}
+