assert from java that jni code has an env

Rare crashes are happening inside the jni, in game_dispose(), when a
game's double-disposed. Adding a jni call to check if the thread about
to do a game_dispose() will fail then asserting its result in java
allows useful stack traces to come via Crittercism. Or should.
This commit is contained in:
Eric House 2016-08-11 16:42:18 -07:00
parent 5d9423f317
commit 8e399ef9b7
3 changed files with 31 additions and 4 deletions

View file

@ -191,8 +191,8 @@ map_destroy( EnvThreadInfo* ti )
pthread_mutex_destroy( &ti->mtxThreads );
}
JNIEnv*
envForMe( EnvThreadInfo* ti, const char* caller )
static JNIEnv*
prvEnvForMe( EnvThreadInfo* ti )
{
JNIEnv* result = NULL;
pthread_t self = pthread_self();
@ -204,7 +204,15 @@ envForMe( EnvThreadInfo* ti, const char* caller )
}
}
pthread_mutex_unlock( &ti->mtxThreads );
return result;
}
JNIEnv*
envForMe( EnvThreadInfo* ti, const char* caller )
{
JNIEnv* result = prvEnvForMe( ti );
if( !result ) {
pthread_t self = pthread_self();
XP_LOGF( "no env for %s (thread %x)", caller, (int)self );
XP_ASSERT(0);
}
@ -1948,6 +1956,15 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getStats
return result;
}
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_haveEnv
( JNIEnv* env, jclass C, jint jniGlobalPtr )
{
JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr;
jboolean result = NULL != prvEnvForMe(&state->ti);
return result;
}
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1endGame
( JNIEnv* env, jclass C, GamePtrType gamePtr )

View file

@ -93,6 +93,7 @@ public class XWApp extends Application {
// This is called on emulator only, but good for ensuring no memory leaks
// by forcing JNI cleanup
@Override
public void onTerminate()
{
DbgUtils.logf( "XwApp.onTerminate() called" );

View file

@ -43,7 +43,11 @@ public class XwJNI {
retain();
}
public int ptr() { Assert.assertTrue( 0 != m_ptr ); return m_ptr; }
public synchronized int ptr()
{
Assert.assertTrue( 0 != m_ptr );
return m_ptr;
}
public synchronized GamePtr retain()
{
@ -62,7 +66,10 @@ public class XwJNI {
this, m_rowid, m_refCount );
if ( 0 == m_refCount ) {
if ( 0 != m_ptr ) {
game_dispose( this );
if ( !haveEnv( getJNI().m_ptr ) ) {
Assert.fail();
}
game_dispose( this ); // will crash if haveEnv fails
m_ptr = 0;
}
}
@ -484,4 +491,6 @@ public class XwJNI {
private static native int dict_iter_init( int jniState, byte[] dict,
String name, String path,
JNIUtils jniu );
private static native boolean haveEnv( int jniState );
}