diff options
Diffstat (limited to 'rs/java/android/renderscript/RenderScript.java')
-rw-r--r-- | rs/java/android/renderscript/RenderScript.java | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java index 147ac15..9c8775a 100644 --- a/rs/java/android/renderscript/RenderScript.java +++ b/rs/java/android/renderscript/RenderScript.java @@ -19,6 +19,7 @@ package android.renderscript; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.concurrent.locks.ReentrantReadWriteLock; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -151,6 +152,7 @@ public class RenderScript { } ContextType mContextType; + ReentrantReadWriteLock mRWLock; // Methods below are wrapped to protect the non-threadsafe // lockless fifo. @@ -178,7 +180,18 @@ public class RenderScript { native void rsnContextDestroy(long con); synchronized void nContextDestroy() { validate(); - rsnContextDestroy(mContext); + + // take teardown lock + // teardown lock can only be taken when no objects are being destroyed + ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock(); + wlock.lock(); + + long curCon = mContext; + // context is considered dead as of this point + mContext = 0; + + wlock.unlock(); + rsnContextDestroy(curCon); } native void rsnContextSetSurface(long con, int w, int h, Surface sur); synchronized void nContextSetSurface(int w, int h, Surface sur) { @@ -263,8 +276,10 @@ public class RenderScript { validate(); return rsnGetName(mContext, obj); } + + // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers native void rsnObjDestroy(long con, long id); - synchronized void nObjDestroy(long id) { + void nObjDestroy(long id) { // There is a race condition here. The calling code may be run // by the gc while teardown is occuring. This protects againts // deleting dead objects. @@ -1096,6 +1111,7 @@ public class RenderScript { if (ctx != null) { mApplicationContext = ctx.getApplicationContext(); } + mRWLock = new ReentrantReadWriteLock(); } /** @@ -1190,6 +1206,8 @@ public class RenderScript { */ public void destroy() { validate(); + nContextFinish(); + nContextDeinitToClient(mContext); mMessageThread.mRun = false; try { @@ -1198,7 +1216,6 @@ public class RenderScript { } nContextDestroy(); - mContext = 0; nDeviceDestroy(mDev); mDev = 0; |