summaryrefslogtreecommitdiffstats
path: root/rs/java
diff options
context:
space:
mode:
authorTim Murray <timmurray@google.com>2014-01-07 11:13:56 -0800
committerTim Murray <timmurray@google.com>2014-01-10 10:39:38 -0800
commit06b4567559bbf39eccfa9c28152c8e5e067cf576 (patch)
tree668d498fdde464a765f3abc183755f25e4683670 /rs/java
parent71a01b8648a440d4773acf0d2376d015c129ebb5 (diff)
downloadframeworks_base-06b4567559bbf39eccfa9c28152c8e5e067cf576.zip
frameworks_base-06b4567559bbf39eccfa9c28152c8e5e067cf576.tar.gz
frameworks_base-06b4567559bbf39eccfa9c28152c8e5e067cf576.tar.bz2
Enable asynchronous destruction of BaseObjs.
Change-Id: Iaddf8041a3c870a986ec8999e6ccc3aede38fc4c
Diffstat (limited to 'rs/java')
-rw-r--r--rs/java/android/renderscript/BaseObj.java32
-rw-r--r--rs/java/android/renderscript/RenderScript.java23
2 files changed, 43 insertions, 12 deletions
diff --git a/rs/java/android/renderscript/BaseObj.java b/rs/java/android/renderscript/BaseObj.java
index 1a15ce6..eee4936 100644
--- a/rs/java/android/renderscript/BaseObj.java
+++ b/rs/java/android/renderscript/BaseObj.java
@@ -16,6 +16,8 @@
package android.renderscript;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
/**
* BaseObj is the base class for all RenderScript objects owned by a RS context.
* It is responsible for lifetime management and resource tracking. This class
@@ -107,17 +109,30 @@ public class BaseObj {
return mName;
}
- protected void finalize() throws Throwable {
- if (!mDestroyed) {
- if(mID != 0 && mRS.isAlive()) {
+ private void helpDestroy() {
+ boolean shouldDestroy = false;
+ synchronized(this) {
+ if (!mDestroyed) {
+ shouldDestroy = true;
+ mDestroyed = true;
+ }
+ }
+
+ if (shouldDestroy) {
+ // must include nObjDestroy in the critical section
+ ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
+ rlock.lock();
+ if(mRS.isAlive()) {
mRS.nObjDestroy(mID);
}
+ rlock.unlock();
mRS = null;
mID = 0;
- mDestroyed = true;
- //Log.v(RenderScript.LOG_TAG, getClass() +
- // " auto finalizing object without having released the RS reference.");
}
+ }
+
+ protected void finalize() throws Throwable {
+ helpDestroy();
super.finalize();
}
@@ -126,12 +141,11 @@ public class BaseObj {
* primary use is to force immediate cleanup of resources when it is
* believed the GC will not respond quickly enough.
*/
- synchronized public void destroy() {
+ public void destroy() {
if(mDestroyed) {
throw new RSInvalidStateException("Object already destroyed.");
}
- mDestroyed = true;
- mRS.nObjDestroy(mID);
+ helpDestroy();
}
/**
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index d2c7456..b0ef156 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -18,6 +18,7 @@ package android.renderscript;
import java.io.File;
import java.lang.reflect.Method;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import android.content.Context;
import android.content.res.AssetManager;
@@ -147,6 +148,7 @@ public class RenderScript {
}
ContextType mContextType;
+ ReentrantReadWriteLock mRWLock;
// Methods below are wrapped to protect the non-threadsafe
// lockless fifo.
@@ -174,7 +176,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) {
@@ -259,8 +272,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.
@@ -1092,6 +1107,7 @@ public class RenderScript {
if (ctx != null) {
mApplicationContext = ctx.getApplicationContext();
}
+ mRWLock = new ReentrantReadWriteLock();
}
/**
@@ -1186,6 +1202,8 @@ public class RenderScript {
*/
public void destroy() {
validate();
+ nContextFinish();
+
nContextDeinitToClient(mContext);
mMessageThread.mRun = false;
try {
@@ -1194,7 +1212,6 @@ public class RenderScript {
}
nContextDestroy();
- mContext = 0;
nDeviceDestroy(mDev);
mDev = 0;