Enable asynchronous destruction of BaseObjs.
Change-Id: Iaddf8041a3c870a986ec8999e6ccc3aede38fc4c Conflicts: rs/java/android/renderscript/BaseObj.java
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
|
||||
package android.renderscript;
|
||||
|
||||
import android.util.Log;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* BaseObj is the base class for all RenderScript objects owned by a RS context.
|
||||
@@ -109,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();
|
||||
}
|
||||
|
||||
@@ -128,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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user