am 0539b7b4: Merge "Enable asynchronous destruction of BaseObjs."
* commit '0539b7b4116622d33c91dbaa9a3040c7a3a703d6': Enable asynchronous destruction of BaseObjs.
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package android.renderscript;
|
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.
|
* BaseObj is the base class for all RenderScript objects owned by a RS context.
|
||||||
@@ -109,17 +109,30 @@ public class BaseObj {
|
|||||||
return mName;
|
return mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void finalize() throws Throwable {
|
private void helpDestroy() {
|
||||||
if (!mDestroyed) {
|
boolean shouldDestroy = false;
|
||||||
if(mID != 0 && mRS.isAlive()) {
|
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);
|
mRS.nObjDestroy(mID);
|
||||||
}
|
}
|
||||||
|
rlock.unlock();
|
||||||
mRS = null;
|
mRS = null;
|
||||||
mID = 0;
|
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();
|
super.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,12 +141,11 @@ public class BaseObj {
|
|||||||
* primary use is to force immediate cleanup of resources when it is
|
* primary use is to force immediate cleanup of resources when it is
|
||||||
* believed the GC will not respond quickly enough.
|
* believed the GC will not respond quickly enough.
|
||||||
*/
|
*/
|
||||||
synchronized public void destroy() {
|
public void destroy() {
|
||||||
if(mDestroyed) {
|
if(mDestroyed) {
|
||||||
throw new RSInvalidStateException("Object already destroyed.");
|
throw new RSInvalidStateException("Object already destroyed.");
|
||||||
}
|
}
|
||||||
mDestroyed = true;
|
helpDestroy();
|
||||||
mRS.nObjDestroy(mID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package android.renderscript;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
@@ -151,6 +152,7 @@ public class RenderScript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContextType mContextType;
|
ContextType mContextType;
|
||||||
|
ReentrantReadWriteLock mRWLock;
|
||||||
|
|
||||||
// Methods below are wrapped to protect the non-threadsafe
|
// Methods below are wrapped to protect the non-threadsafe
|
||||||
// lockless fifo.
|
// lockless fifo.
|
||||||
@@ -178,7 +180,18 @@ public class RenderScript {
|
|||||||
native void rsnContextDestroy(long con);
|
native void rsnContextDestroy(long con);
|
||||||
synchronized void nContextDestroy() {
|
synchronized void nContextDestroy() {
|
||||||
validate();
|
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);
|
native void rsnContextSetSurface(long con, int w, int h, Surface sur);
|
||||||
synchronized void nContextSetSurface(int w, int h, Surface sur) {
|
synchronized void nContextSetSurface(int w, int h, Surface sur) {
|
||||||
@@ -263,8 +276,10 @@ public class RenderScript {
|
|||||||
validate();
|
validate();
|
||||||
return rsnGetName(mContext, obj);
|
return rsnGetName(mContext, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
|
||||||
native void rsnObjDestroy(long con, long id);
|
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
|
// There is a race condition here. The calling code may be run
|
||||||
// by the gc while teardown is occuring. This protects againts
|
// by the gc while teardown is occuring. This protects againts
|
||||||
// deleting dead objects.
|
// deleting dead objects.
|
||||||
@@ -1096,6 +1111,7 @@ public class RenderScript {
|
|||||||
if (ctx != null) {
|
if (ctx != null) {
|
||||||
mApplicationContext = ctx.getApplicationContext();
|
mApplicationContext = ctx.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
mRWLock = new ReentrantReadWriteLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1190,6 +1206,8 @@ public class RenderScript {
|
|||||||
*/
|
*/
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
validate();
|
validate();
|
||||||
|
nContextFinish();
|
||||||
|
|
||||||
nContextDeinitToClient(mContext);
|
nContextDeinitToClient(mContext);
|
||||||
mMessageThread.mRun = false;
|
mMessageThread.mRun = false;
|
||||||
try {
|
try {
|
||||||
@@ -1198,7 +1216,6 @@ public class RenderScript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nContextDestroy();
|
nContextDestroy();
|
||||||
mContext = 0;
|
|
||||||
|
|
||||||
nDeviceDestroy(mDev);
|
nDeviceDestroy(mDev);
|
||||||
mDev = 0;
|
mDev = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user