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/java/Fountain/src/com/android/fountain/Fountain.java b/java/Fountain/src/com/android/fountain/Fountain.java
index 58c78fa..9ae3e67 100644
--- a/java/Fountain/src/com/android/fountain/Fountain.java
+++ b/java/Fountain/src/com/android/fountain/Fountain.java
@@ -62,6 +62,8 @@
 
     @Override
     protected void onResume() {
+        Log.e("rs", "onResume");
+
         // Ideally a game should implement onResume() and onPause()
         // to take appropriate action when the activity looses focus
         super.onResume();
@@ -70,12 +72,16 @@
 
     @Override
     protected void onPause() {
+        Log.e("rs", "onPause");
+
         // Ideally a game should implement onResume() and onPause()
         // to take appropriate action when the activity looses focus
         super.onPause();
         mView.onPause();
 
-        Runtime.getRuntime().exit(0);
+
+
+        //Runtime.getRuntime().exit(0);
     }
 
 
diff --git a/java/Fountain/src/com/android/fountain/FountainView.java b/java/Fountain/src/com/android/fountain/FountainView.java
index 1b07f98..116afd0 100644
--- a/java/Fountain/src/com/android/fountain/FountainView.java
+++ b/java/Fountain/src/com/android/fountain/FountainView.java
@@ -49,14 +49,40 @@
     private RenderScript mRS;
     private FountainRS mRender;
 
+    private void destroyRS() {
+        if(mRS != null) {
+            mRS = null;
+            destroyRenderScript();
+        }
+        java.lang.System.gc();
+    }
+
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
         super.surfaceChanged(holder, format, w, h);
 
+        Log.e("rs", "surfaceChanged");
+        destroyRS();
+
+
         mRS = createRenderScript(false, true);
         mRender = new FountainRS();
         mRender.init(mRS, getResources(), w, h);
     }
 
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // Surface will be destroyed when we return
+        Log.v("rs", "surfaceDestroyed");
+        destroyRS();
+
+        try {
+            java.lang.Thread.sleep(5000);
+        } catch(InterruptedException e) {
+
+        }
+        Runtime.getRuntime().exit(0);
+    }
+
+
 
     @Override
     public boolean onTouchEvent(MotionEvent ev)
diff --git a/rsAdapter.cpp b/rsAdapter.cpp
index d20e910..9a3bbb1 100644
--- a/rsAdapter.cpp
+++ b/rsAdapter.cpp
@@ -21,12 +21,12 @@
 using namespace android::renderscript;
 
 
-Adapter1D::Adapter1D()
+Adapter1D::Adapter1D(Context *rsc) : ObjectBase(rsc)
 {
     reset();
 }
 
-Adapter1D::Adapter1D(Allocation *a)
+Adapter1D::Adapter1D(Context *rsc, Allocation *a) : ObjectBase(rsc)
 {
     reset();
     setAllocation(a);
@@ -71,7 +71,7 @@
 
 RsAdapter1D rsi_Adapter1DCreate(Context *rsc)
 {
-    Adapter1D *a = new Adapter1D();
+    Adapter1D *a = new Adapter1D(rsc);
     a->incUserRef();
     return a;
 }
@@ -125,12 +125,12 @@
 
 //////////////////////////
 
-Adapter2D::Adapter2D()
+Adapter2D::Adapter2D(Context *rsc) : ObjectBase(rsc)
 {
     reset();
 }
 
-Adapter2D::Adapter2D(Allocation *a)
+Adapter2D::Adapter2D(Context *rsc, Allocation *a) : ObjectBase(rsc)
 {
     reset();
     setAllocation(a);
@@ -184,7 +184,7 @@
 
 RsAdapter2D rsi_Adapter2DCreate(Context *rsc)
 {
-    Adapter2D *a = new Adapter2D();
+    Adapter2D *a = new Adapter2D(rsc);
     a->incUserRef();
     return a;
 }
diff --git a/rsAdapter.h b/rsAdapter.h
index 865535e..cb2872e 100644
--- a/rsAdapter.h
+++ b/rsAdapter.h
@@ -23,15 +23,15 @@
 namespace android {
 namespace renderscript {
 
-    
+
 class Adapter1D : public ObjectBase
 {
 
 public:
     // By policy this allocation will hold a pointer to the type
     // but will not destroy it on destruction.
-    Adapter1D();
-    Adapter1D(Allocation *);
+    Adapter1D(Context *);
+    Adapter1D(Context *, Allocation *);
     void reset();
     void * getElement(uint32_t x);
 
@@ -64,8 +64,8 @@
 public:
     // By policy this allocation will hold a pointer to the type
     // but will not destroy it on destruction.
-    Adapter2D();
-    Adapter2D(Allocation *);
+    Adapter2D(Context *);
+    Adapter2D(Context *, Allocation *);
     void reset();
     void * getElement(uint32_t x, uint32_t y) const;
 
@@ -79,8 +79,8 @@
     inline void setFace(uint32_t face) {mFace = face;}
     //void setArray(uint32_t num, uint32_t value);
 
-    void data(const void *data); 
-    void subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data); 
+    void data(const void *data);
+    void subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data);
 
 protected:
     ObjectBaseRef<Allocation> mAllocation;
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index cb82624..96e128b 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -22,7 +22,7 @@
 using namespace android;
 using namespace android::renderscript;
 
-Allocation::Allocation(const Type *type)
+Allocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc)
 {
     mPtr = NULL;
 
@@ -90,7 +90,7 @@
     }
     glBindTexture(GL_TEXTURE_2D, mTextureID);
 
-    Adapter2D adapt(this);
+    Adapter2D adapt(getContext(), this);
     for(uint32_t lod = 0; (lod + lodOffset) < mType->getLODCount(); lod++) {
         adapt.setLOD(lod+lodOffset);
 
@@ -186,14 +186,14 @@
 {
     const Type * type = static_cast<const Type *>(vtype);
 
-    Allocation * alloc = new Allocation(type);
+    Allocation * alloc = new Allocation(rsc, type);
     alloc->incUserRef();
     return alloc;
 }
 
 RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count)
 {
-    Type * type = new Type();
+    Type * type = new Type(rsc);
     type->setDimX(count);
     type->setElement(static_cast<Element *>(e));
     type->compute();
@@ -371,8 +371,8 @@
     cvt(texAlloc->getPtr(), data, w * h);
 
     if (genMips) {
-        Adapter2D adapt(texAlloc);
-        Adapter2D adapt2(texAlloc);
+        Adapter2D adapt(rsc, texAlloc);
+        Adapter2D adapt2(rsc, texAlloc);
         for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
             adapt.setLOD(lod);
             adapt2.setLOD(lod + 1);
diff --git a/rsAllocation.h b/rsAllocation.h
index 1f58ec5..1b83267 100644
--- a/rsAllocation.h
+++ b/rsAllocation.h
@@ -33,7 +33,7 @@
 public:
     // By policy this allocation will hold a pointer to the type
     // but will not destroy it on destruction.
-    Allocation(const Type *);
+    Allocation(Context *rsc, const Type *);
     virtual ~Allocation();
 
     void setCpuWritable(bool);
diff --git a/rsComponent.cpp b/rsComponent.cpp
index 4a043f3..67184ff 100644
--- a/rsComponent.cpp
+++ b/rsComponent.cpp
@@ -21,7 +21,7 @@
 using namespace android::renderscript;
 
 
-Component::Component()
+Component::Component(Context *rsc) : ObjectBase(rsc)
 {
     mType = FLOAT;
     mKind = USER;
@@ -29,9 +29,9 @@
     mBits = 0;
 }
 
-Component::Component(
+Component::Component(Context *rsc,
     DataKind dk, DataType dt,
-    bool isNormalized, uint32_t bits, const char * name)
+    bool isNormalized, uint32_t bits, const char * name) : ObjectBase(rsc)
 {
     mType = dt;
     mKind = dk;
diff --git a/rsComponent.h b/rsComponent.h
index 5856524..290cd57 100644
--- a/rsComponent.h
+++ b/rsComponent.h
@@ -44,7 +44,7 @@
     };
 
 
-    Component(DataKind dk, DataType dt, bool isNorm, uint32_t bits, const char *);
+    Component(Context *rsc, DataKind dk, DataType dt, bool isNorm, uint32_t bits, const char *);
     virtual ~Component();
 
     DataType getType() const {return mType;}
@@ -66,7 +66,7 @@
     String8 mName;
 
 private:
-    Component();
+    Component(Context *rsc);
 };
 
 
diff --git a/rsContext.cpp b/rsContext.cpp
index 2fe762c..6c18ddb 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -269,6 +269,12 @@
      }
 
      LOGV("RS Thread exiting");
+     ObjectBase::zeroAllUserRef(rsc);
+     rsc->mRaster.set(NULL);
+     rsc->mFragment.set(NULL);
+     rsc->mVertex.set(NULL);
+     rsc->mFragmentStore.set(NULL);
+
      glClearColor(0,0,0,0);
      glClear(GL_COLOR_BUFFER_BIT);
      eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
@@ -286,6 +292,7 @@
     mExit = false;
     mUseDepth = useDepth;
     mPaused = false;
+    mObjHead = NULL;
 
     int status;
     pthread_attr_t threadAttr;
diff --git a/rsContext.h b/rsContext.h
index 0a886cd..28a9de2 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -145,6 +145,8 @@
 
     bool logTimes;
 
+    mutable const ObjectBase * mObjHead;
+
 protected:
     Device *mDev;
 
diff --git a/rsElement.cpp b/rsElement.cpp
index b5267b3..e7ae247 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -22,13 +22,13 @@
 using namespace android::renderscript;
 
 
-Element::Element()
+Element::Element(Context *rsc) : ObjectBase(rsc)
 {
     mComponents = NULL;
     mComponentCount = 0;
 }
 
-Element::Element(uint32_t count)
+Element::Element(Context *rsc, uint32_t count) : ObjectBase(rsc)
 {
     mComponents = new ObjectBaseRef<Component> [count];
     mComponentCount = count;
@@ -197,7 +197,8 @@
 void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name)
 {
     ElementState * sec = &rsc->mStateElement;
-    Component *c = new Component(static_cast<Component::DataKind>(dk),
+    Component *c = new Component(rsc,
+                                 static_cast<Component::DataKind>(dk),
                                  static_cast<Component::DataType>(dt),
                                  isNormalized,
                                  bits,
@@ -208,7 +209,7 @@
 RsElement rsi_ElementCreate(Context *rsc)
 {
     ElementState * sec = &rsc->mStateElement;
-    Element *se = new Element(sec->mComponentBuildList.size());
+    Element *se = new Element(rsc, sec->mComponentBuildList.size());
 
     for (size_t ct = 0; ct < se->getComponentCount(); ct++) {
         se->setComponent(ct, sec->mComponentBuildList[ct]);
diff --git a/rsElement.h b/rsElement.h
index 7b5a83d..82da441 100644
--- a/rsElement.h
+++ b/rsElement.h
@@ -28,7 +28,7 @@
 class Element : public ObjectBase
 {
 public:
-    Element(uint32_t count);
+    Element(Context *, uint32_t count);
     ~Element();
 
 
@@ -59,7 +59,7 @@
     ObjectBaseRef<Component> * mComponents;
     //uint32_t *mOffsetTable;
 
-    Element();
+    Element(Context *);
 };
 
 
diff --git a/rsFileA3D.cpp b/rsFileA3D.cpp
index 347ef23..c566665 100644
--- a/rsFileA3D.cpp
+++ b/rsFileA3D.cpp
@@ -242,7 +242,7 @@
 
 void FileA3D::processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie)
 {
-    Mesh * m = new Mesh;
+    Mesh * m = new Mesh(rsc);
 
     m->mPrimitivesCount = io->loadU32();
     m->mPrimitives = new Mesh::Primitive_t *[m->mPrimitivesCount];
diff --git a/rsLight.cpp b/rsLight.cpp
index ad06c1f..e9b8ef9 100644
--- a/rsLight.cpp
+++ b/rsLight.cpp
@@ -22,7 +22,7 @@
 using namespace android::renderscript;
 
 
-Light::Light(bool isLocal, bool isMono)
+Light::Light(Context *rsc, bool isLocal, bool isMono) : ObjectBase(rsc)
 {
     mIsLocal = isLocal;
     mIsMono = isMono;
@@ -104,7 +104,7 @@
 
 RsLight rsi_LightCreate(Context *rsc)
 {
-    Light *l = new Light(rsc->mStateLight.mIsLocal,
+    Light *l = new Light(rsc, rsc->mStateLight.mIsLocal,
                          rsc->mStateLight.mIsMono);
     l->incUserRef();
     return l;
diff --git a/rsLight.h b/rsLight.h
index b0c3386..d8796e6 100644
--- a/rsLight.h
+++ b/rsLight.h
@@ -29,7 +29,7 @@
 class Light : public ObjectBase
 {
 public:
-    Light(bool isLocal, bool isMono);
+    Light(Context *, bool isLocal, bool isMono);
     virtual ~Light();
 
     // Values, mutable after creation.
diff --git a/rsLocklessFifo.cpp b/rsLocklessFifo.cpp
index f4f5d40..b0540a6 100644
--- a/rsLocklessFifo.cpp
+++ b/rsLocklessFifo.cpp
@@ -131,6 +131,12 @@
             mSignalToWorker.wait();
         }
 
+        if (mInShutdown) {
+            *command = 0;
+            *bytesData = 0;
+            return 0;
+        }
+
         *command = reinterpret_cast<const uint16_t *>(mGet)[0];
         *bytesData = reinterpret_cast<const uint16_t *>(mGet)[1];
         if (*command) {
diff --git a/rsMesh.cpp b/rsMesh.cpp
index aeb52ed..73aef62 100644
--- a/rsMesh.cpp
+++ b/rsMesh.cpp
@@ -22,7 +22,7 @@
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
-Mesh::Mesh()
+Mesh::Mesh(Context *rsc) : ObjectBase(rsc)
 {
     mVerticies = NULL;
     mVerticiesCount = 0;
diff --git a/rsMesh.h b/rsMesh.h
index be207a3..5201abd 100644
--- a/rsMesh.h
+++ b/rsMesh.h
@@ -29,7 +29,7 @@
 class Mesh : public ObjectBase
 {
 public:
-    Mesh();
+    Mesh(Context *);
     ~Mesh();
 
     struct Verticies_t
@@ -42,7 +42,7 @@
         size_t mOffsetCoord;
         size_t mOffsetTex;
         size_t mOffsetNorm;
-    
+
         size_t mSizeCoord;
         size_t mSizeTex;
         size_t mSizeNorm;
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);
+        }
+    }
+}
+
diff --git a/rsObjectBase.h b/rsObjectBase.h
index d1e6baa..be400ca 100644
--- a/rsObjectBase.h
+++ b/rsObjectBase.h
@@ -23,18 +23,21 @@
 namespace android {
 namespace renderscript {
 
+class Context;
+
 // An element is a group of Components that occupies one cell in a structure.
 class ObjectBase
 {
 public:
-    ObjectBase();
+    ObjectBase(Context *rsc);
     virtual ~ObjectBase();
 
     void incSysRef() const;
-    void decSysRef() const;
+    bool decSysRef() const;
 
     void incUserRef() const;
-    void decUserRef() const;
+    bool decUserRef() const;
+    bool zeroUserRef() const;
 
     const char * getName() const {
         return mName;
@@ -42,12 +45,24 @@
     void setName(const char *);
     void setName(const char *, uint32_t len);
 
+    Context * getContext() const {return mRSC;}
+    void setContext(Context *);
+
+    static void zeroAllUserRef(Context *rsc);
+
 private:
+    void add() const;
+    void remove() const;
+
+    bool checkDelete() const;
+
     char * mName;
+    Context *mRSC;
     mutable int32_t mSysRefCount;
     mutable int32_t mUserRefCount;
 
-
+    mutable const ObjectBase * mPrev;
+    mutable const ObjectBase * mNext;
 };
 
 template<class T>
diff --git a/rsProgram.cpp b/rsProgram.cpp
index 18eacfb..051483f 100644
--- a/rsProgram.cpp
+++ b/rsProgram.cpp
@@ -21,7 +21,7 @@
 using namespace android::renderscript;
 
 
-Program::Program(Element *in, Element *out)
+Program::Program(Context *rsc, Element *in, Element *out) : ObjectBase(rsc)
 {
     mElementIn.set(in);
     mElementOut.set(out);
diff --git a/rsProgram.h b/rsProgram.h
index bb3d9ac..26b78dd 100644
--- a/rsProgram.h
+++ b/rsProgram.h
@@ -29,7 +29,7 @@
 class Program : public ObjectBase
 {
 public:
-    Program(Element *in, Element *out);
+    Program(Context *, Element *in, Element *out);
     virtual ~Program();
 
     void bindAllocation(Allocation *);
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index 6cf64a4..5f685ff 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -24,8 +24,8 @@
 using namespace android::renderscript;
 
 
-ProgramFragment::ProgramFragment(Element *in, Element *out, bool pointSpriteEnable) :
-    Program(in, out)
+ProgramFragment::ProgramFragment(Context *rsc, Element *in, Element *out, bool pointSpriteEnable) :
+    Program(rsc, in, out)
 {
     for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
         mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE;
@@ -186,7 +186,7 @@
 
 void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
 {
-    ProgramFragment *pf = new ProgramFragment(NULL, NULL, false);
+    ProgramFragment *pf = new ProgramFragment(rsc, NULL, NULL, false);
     mDefault.set(pf);
 }
 
@@ -197,7 +197,7 @@
 void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable)
 {
     delete rsc->mStateFragment.mPF;
-    rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out, pointSpriteEnable);
+    rsc->mStateFragment.mPF = new ProgramFragment(rsc, (Element *)in, (Element *)out, pointSpriteEnable);
 }
 
 void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
diff --git a/rsProgramFragment.h b/rsProgramFragment.h
index 51117eb..d783c0d 100644
--- a/rsProgramFragment.h
+++ b/rsProgramFragment.h
@@ -32,7 +32,7 @@
 
 
 
-    ProgramFragment(Element *in, Element *out, bool pointSpriteEnable);
+    ProgramFragment(Context *, Element *in, Element *out, bool pointSpriteEnable);
     virtual ~ProgramFragment();
 
     virtual void setupGL(const Context *, ProgramFragmentState *);
diff --git a/rsProgramFragmentStore.cpp b/rsProgramFragmentStore.cpp
index 3179484..39802c7 100644
--- a/rsProgramFragmentStore.cpp
+++ b/rsProgramFragmentStore.cpp
@@ -24,8 +24,8 @@
 using namespace android::renderscript;
 
 
-ProgramFragmentStore::ProgramFragmentStore(Element *in, Element *out) :
-    Program(in, out)
+ProgramFragmentStore::ProgramFragmentStore(Context *rsc, Element *in, Element *out) :
+    Program(rsc, in, out)
 {
     mDitherEnable = true;
     mBlendEnable = false;
@@ -213,7 +213,7 @@
 
 void ProgramFragmentStoreState::init(Context *rsc, int32_t w, int32_t h)
 {
-    ProgramFragmentStore *pfs = new ProgramFragmentStore(NULL, NULL);
+    ProgramFragmentStore *pfs = new ProgramFragmentStore(rsc, NULL, NULL);
     mDefault.set(pfs);
 }
 
@@ -224,7 +224,7 @@
 void rsi_ProgramFragmentStoreBegin(Context * rsc, RsElement in, RsElement out)
 {
     delete rsc->mStateFragmentStore.mPFS;
-    rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore((Element *)in, (Element *)out);
+    rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore(rsc, (Element *)in, (Element *)out);
 
 }
 
diff --git a/rsProgramFragmentStore.h b/rsProgramFragmentStore.h
index e646e03..b71e35f 100644
--- a/rsProgramFragmentStore.h
+++ b/rsProgramFragmentStore.h
@@ -28,7 +28,7 @@
 class ProgramFragmentStore : public Program
 {
 public:
-    ProgramFragmentStore(Element *in, Element *out);
+    ProgramFragmentStore(Context *, Element *in, Element *out);
     virtual ~ProgramFragmentStore();
 
     virtual void setupGL(const Context *, ProgramFragmentStoreState *);
diff --git a/rsProgramRaster.cpp b/rsProgramRaster.cpp
index b968fe1..2a9c4ab 100644
--- a/rsProgramRaster.cpp
+++ b/rsProgramRaster.cpp
@@ -24,12 +24,13 @@
 using namespace android::renderscript;
 
 
-ProgramRaster::ProgramRaster(Element *in,
+ProgramRaster::ProgramRaster(Context *rsc,
+                             Element *in,
                              Element *out,
                              bool pointSmooth,
                              bool lineSmooth,
                              bool pointSprite) :
-    Program(in, out)
+    Program(rsc, in, out)
 {
     mPointSmooth = pointSmooth;
     mLineSmooth = lineSmooth;
@@ -95,7 +96,7 @@
 
 void ProgramRasterState::init(Context *rsc, int32_t w, int32_t h)
 {
-    ProgramRaster *pr = new ProgramRaster(NULL, NULL, false, false, false);
+    ProgramRaster *pr = new ProgramRaster(rsc, NULL, NULL, false, false, false);
     mDefault.set(pr);
 }
 
@@ -108,7 +109,8 @@
                                       bool lineSmooth,
                                       bool pointSprite)
 {
-    ProgramRaster *pr = new ProgramRaster(static_cast<Element *>(in),
+    ProgramRaster *pr = new ProgramRaster(rsc,
+                                          static_cast<Element *>(in),
                                           static_cast<Element *>(out),
                                           pointSmooth,
                                           lineSmooth,
diff --git a/rsProgramRaster.h b/rsProgramRaster.h
index 5984868..da68f67 100644
--- a/rsProgramRaster.h
+++ b/rsProgramRaster.h
@@ -28,7 +28,8 @@
 class ProgramRaster : public Program
 {
 public:
-    ProgramRaster(Element *in,
+    ProgramRaster(Context *rsc,
+                  Element *in,
                   Element *out,
                   bool pointSmooth,
                   bool lineSmooth,
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index dda56d7..9eb32ff 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -24,8 +24,8 @@
 using namespace android::renderscript;
 
 
-ProgramVertex::ProgramVertex(Element *in, Element *out) :
-    Program(in, out)
+ProgramVertex::ProgramVertex(Context *rsc, Element *in, Element *out) :
+    Program(rsc, in, out)
 {
     mTextureMatrixEnable = false;
     mLightCount = 0;
@@ -141,7 +141,7 @@
     rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
     mAllocType = rsi_TypeCreate(rsc);
 
-    ProgramVertex *pv = new ProgramVertex(NULL, NULL);
+    ProgramVertex *pv = new ProgramVertex(rsc, NULL, NULL);
     Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType);
     mDefaultAlloc.set(alloc);
     mDefault.set(pv);
@@ -163,7 +163,7 @@
 void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out)
 {
     delete rsc->mStateVertex.mPV;
-    rsc->mStateVertex.mPV = new ProgramVertex((Element *)in, (Element *)out);
+    rsc->mStateVertex.mPV = new ProgramVertex(rsc, (Element *)in, (Element *)out);
 }
 
 RsProgramVertex rsi_ProgramVertexCreate(Context *rsc)
diff --git a/rsProgramVertex.h b/rsProgramVertex.h
index 32d147c..b3a8b8d 100644
--- a/rsProgramVertex.h
+++ b/rsProgramVertex.h
@@ -30,7 +30,7 @@
 public:
     const static uint32_t MAX_LIGHTS = 8;
 
-    ProgramVertex(Element *in, Element *out);
+    ProgramVertex(Context *, Element *in, Element *out);
     virtual ~ProgramVertex();
 
     virtual void setupGL(const Context *rsc, ProgramVertexState *state);
diff --git a/rsSampler.cpp b/rsSampler.cpp
index 3f56faa..99091a9 100644
--- a/rsSampler.cpp
+++ b/rsSampler.cpp
@@ -25,17 +25,18 @@
 using namespace android::renderscript;
 
 
-Sampler::Sampler()
+Sampler::Sampler(Context *rsc) : ObjectBase(rsc)
 {
     // Should not get called.
     rsAssert(0);
 }
 
-Sampler::Sampler(RsSamplerValue magFilter,
+Sampler::Sampler(Context *rsc,
+                 RsSamplerValue magFilter,
                  RsSamplerValue minFilter,
                  RsSamplerValue wrapS,
                  RsSamplerValue wrapT,
-                 RsSamplerValue wrapR)
+                 RsSamplerValue wrapR) : ObjectBase(rsc)
 {
     mMagFilter = magFilter;
     mMinFilter = minFilter;
@@ -138,7 +139,8 @@
     SamplerState * ss = &rsc->mStateSampler;
 
 
-    Sampler * s = new Sampler(ss->mMagFilter,
+    Sampler * s = new Sampler(rsc,
+                              ss->mMagFilter,
                               ss->mMinFilter,
                               ss->mWrapS,
                               ss->mWrapT,
diff --git a/rsSampler.h b/rsSampler.h
index 4b504f6..ccf9b4d 100644
--- a/rsSampler.h
+++ b/rsSampler.h
@@ -31,7 +31,8 @@
 class Sampler : public ObjectBase
 {
 public:
-    Sampler(RsSamplerValue magFilter,
+    Sampler(Context *,
+            RsSamplerValue magFilter,
             RsSamplerValue minFilter,
             RsSamplerValue wrapS,
             RsSamplerValue wrapT,
@@ -55,12 +56,12 @@
     int32_t mBoundSlot;
 
 private:
-    Sampler();
+    Sampler(Context *);
 
 };
 
 
-class SamplerState 
+class SamplerState
 {
 public:
 
diff --git a/rsScript.cpp b/rsScript.cpp
index 76fed3b..f9526fe 100644
--- a/rsScript.cpp
+++ b/rsScript.cpp
@@ -19,7 +19,7 @@
 using namespace android;
 using namespace android::renderscript;
 
-Script::Script()
+Script::Script(Context *rsc) : ObjectBase(rsc)
 {
     memset(&mEnviroment, 0, sizeof(mEnviroment));
     mEnviroment.mClearColor[0] = 0;
diff --git a/rsScript.h b/rsScript.h
index 97cb67a..0067fc8 100644
--- a/rsScript.h
+++ b/rsScript.h
@@ -36,7 +36,7 @@
 public:
     typedef void (* InvokeFunc_t)(void);
 
-    Script();
+    Script(Context *);
     virtual ~Script();
 
 
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index 22d42ac..fc2744f 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -33,7 +33,7 @@
     ScriptC * sc = (ScriptC *) tls->mScript
 
 
-ScriptC::ScriptC()
+ScriptC::ScriptC(Context *rsc) : Script(rsc)
 {
     mAccScript = NULL;
     memset(&mProgram, 0, sizeof(mProgram));
@@ -106,7 +106,7 @@
     }
 
     delete mScript;
-    mScript = new ScriptC();
+    mScript = new ScriptC(NULL);
 
     mInt32Defines.clear();
     mFloatDefines.clear();
@@ -391,6 +391,7 @@
 
     ss->runCompiler(rsc, s);
     s->incUserRef();
+    s->setContext(rsc);
     for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
         s->mTypes[ct].set(ss->mConstantBufferTypes[ct].get());
         s->mSlotNames[ct] = ss->mSlotNames[ct];
diff --git a/rsScriptC.h b/rsScriptC.h
index 16eb8de..96161d8 100644
--- a/rsScriptC.h
+++ b/rsScriptC.h
@@ -37,7 +37,7 @@
     typedef int (*RunScript_t)(uint32_t launchIndex);
     typedef void (*VoidFunc_t)();
 
-    ScriptC();
+    ScriptC(Context *);
     virtual ~ScriptC();
 
     struct Program_t {
diff --git a/rsSimpleMesh.cpp b/rsSimpleMesh.cpp
index 447bcee..fe06e0c 100644
--- a/rsSimpleMesh.cpp
+++ b/rsSimpleMesh.cpp
@@ -22,7 +22,7 @@
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
-SimpleMesh::SimpleMesh()
+SimpleMesh::SimpleMesh(Context *rsc) : ObjectBase(rsc)
 {
 }
 
@@ -104,7 +104,7 @@
 
 RsSimpleMesh rsi_SimpleMeshCreate(Context *rsc, RsType prim, RsType idx, RsType *vtx, uint32_t vtxCount, uint32_t primType)
 {
-    SimpleMesh *sm = new SimpleMesh();
+    SimpleMesh *sm = new SimpleMesh(rsc);
     sm->incUserRef();
 
     sm->mIndexType.set((const Type *)idx);
diff --git a/rsSimpleMesh.h b/rsSimpleMesh.h
index dc5e19c..1e5c908 100644
--- a/rsSimpleMesh.h
+++ b/rsSimpleMesh.h
@@ -29,7 +29,7 @@
 class SimpleMesh : public ObjectBase
 {
 public:
-    SimpleMesh();
+    SimpleMesh(Context *);
     ~SimpleMesh();
 
     ObjectBaseRef<const Type> mIndexType;
diff --git a/rsThreadIO.cpp b/rsThreadIO.cpp
index 4072f06..964901a 100644
--- a/rsThreadIO.cpp
+++ b/rsThreadIO.cpp
@@ -46,6 +46,10 @@
             con->timerSet(Context::RS_TIMER_IDLE);
         }
         const void * data = mToCore.get(&cmdID, &cmdSize);
+        if (!cmdSize) {
+            // exception occured, probably shutdown.
+            return false;
+        }
         if (con->logTimes) {
             con->timerSet(Context::RS_TIMER_INTERNAL);
         }
diff --git a/rsType.cpp b/rsType.cpp
index 1838fa6..010e49b 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -20,7 +20,7 @@
 using namespace android;
 using namespace android::renderscript;
 
-Type::Type()
+Type::Type(Context *rsc) : ObjectBase(rsc)
 {
     mLODs = 0;
     mLODCount = 0;
@@ -363,7 +363,7 @@
 {
     TypeState * stc = &rsc->mStateType;
 
-    Type * st = new Type();
+    Type * st = new Type(rsc);
     st->incUserRef();
     st->setDimX(stc->mX);
     st->setDimY(stc->mY);
diff --git a/rsType.h b/rsType.h
index 6c39a4c..087e50d 100644
--- a/rsType.h
+++ b/rsType.h
@@ -27,7 +27,7 @@
 class Type : public ObjectBase
 {
 public:
-    Type();
+    Type(Context *);
     virtual ~Type();
 
     Type * createTex2D(const Element *, size_t w, size_t h, bool mip);