mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-29 08:34:37 +01:00
replace stacked tracking of env with explicit mapping from pthread to
env for that thread to fix occasional assertion failure that indicated I was using the wrong env occasionally. I'm not super confident in this because I've seen the env for a thread change, but that could be due to reuse of the thread id.
This commit is contained in:
parent
046710dd54
commit
3fe3b1724a
10 changed files with 164 additions and 87 deletions
|
@ -24,6 +24,8 @@
|
|||
#include "dictnry.h"
|
||||
#include "game.h"
|
||||
|
||||
typedef struct _JNIState JNIState;
|
||||
|
||||
typedef struct _AndGlobals {
|
||||
VTableMgr* vtMgr;
|
||||
CurGameInfo* gi;
|
||||
|
@ -31,7 +33,12 @@ typedef struct _AndGlobals {
|
|||
XW_UtilCtxt* util;
|
||||
struct JNIUtilCtxt* jniutil;
|
||||
TransportProcs* xportProcs;
|
||||
struct JNIState* state;
|
||||
JNIState* state;
|
||||
} AndGlobals;
|
||||
|
||||
typedef struct _EnvThreadInfo EnvThreadInfo;
|
||||
|
||||
JNIEnv* envForMe( EnvThreadInfo* ti, const char* caller );
|
||||
#define ENVFORME( ti ) envForMe( (ti), __func__ )
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,7 @@ enum {
|
|||
|
||||
typedef struct _AndDraw {
|
||||
DrawCtxVTable* vtable;
|
||||
JNIEnv** env;
|
||||
EnvThreadInfo* ti;
|
||||
jobject jdraw; /* global ref; free it! */
|
||||
XP_LangCode curLang;
|
||||
jobject jCache[JCACHE_COUNT];
|
||||
|
@ -48,7 +48,7 @@ typedef struct _AndDraw {
|
|||
static jobject
|
||||
makeJRect( AndDraw* draw, int indx, const XP_Rect* rect )
|
||||
{
|
||||
JNIEnv* env = *draw->env;
|
||||
JNIEnv* env = ENVFORME( draw->ti );
|
||||
jobject robj = draw->jCache[indx];
|
||||
int right = rect->left + rect->width;
|
||||
int bottom = rect->top + rect->height;
|
||||
|
@ -87,7 +87,7 @@ static jobject
|
|||
makeJRects( AndDraw* draw, int indx, XP_U16 nPlayers, const XP_Rect rects[] )
|
||||
{
|
||||
XP_U16 ii;
|
||||
JNIEnv* env = *draw->env;
|
||||
JNIEnv* env = ENVFORME( draw->ti );
|
||||
jobject jrects = draw->jCache[indx];
|
||||
if ( !jrects ) {
|
||||
jclass rclass = (*env)->FindClass( env, "android/graphics/Rect");
|
||||
|
@ -122,7 +122,7 @@ static jobject
|
|||
makeDSIs( AndDraw* draw, int indx, XP_U16 nPlayers, const DrawScoreInfo dsis[] )
|
||||
{
|
||||
XP_U16 ii;
|
||||
JNIEnv* env = *draw->env;
|
||||
JNIEnv* env = ENVFORME( draw->ti );
|
||||
jobject dsiobjs = draw->jCache[indx];
|
||||
|
||||
if ( !dsiobjs ) {
|
||||
|
@ -164,7 +164,7 @@ makeDSIs( AndDraw* draw, int indx, XP_U16 nPlayers, const DrawScoreInfo dsis[] )
|
|||
static jobject
|
||||
makeDSI( AndDraw* draw, int indx, const DrawScoreInfo* dsi )
|
||||
{
|
||||
JNIEnv* env = *draw->env;
|
||||
JNIEnv* env = ENVFORME( draw->ti );
|
||||
jobject dsiobj = draw->jCache[indx];
|
||||
|
||||
if ( !dsiobj ) {
|
||||
|
@ -193,7 +193,7 @@ makeDSI( AndDraw* draw, int indx, const DrawScoreInfo* dsi )
|
|||
|
||||
#define DRAW_CBK_HEADER(nam,sig) \
|
||||
AndDraw* draw = (AndDraw*)dctx; \
|
||||
JNIEnv* env = *draw->env; \
|
||||
JNIEnv* env = ENVFORME( draw->ti ); \
|
||||
XP_ASSERT( !!draw->jdraw ); \
|
||||
jmethodID mid = getMethodID( env, draw->jdraw, nam, sig );
|
||||
|
||||
|
@ -600,15 +600,15 @@ draw_doNothing( DrawCtx* dctx, ... )
|
|||
} /* draw_doNothing */
|
||||
|
||||
DrawCtx*
|
||||
makeDraw( MPFORMAL JNIEnv** envp, jobject jdraw )
|
||||
makeDraw( MPFORMAL EnvThreadInfo* ti, jobject jdraw )
|
||||
{
|
||||
AndDraw* draw = (AndDraw*)XP_CALLOC( mpool, sizeof(*draw) );
|
||||
JNIEnv* env = *envp;
|
||||
JNIEnv* env = ENVFORME( ti );
|
||||
draw->vtable = XP_MALLOC( mpool, sizeof(*draw->vtable) );
|
||||
if ( NULL != jdraw ) {
|
||||
draw->jdraw = (*env)->NewGlobalRef( env, jdraw );
|
||||
}
|
||||
draw->env = envp;
|
||||
draw->ti = ti;
|
||||
MPASSIGN( draw->mpool, mpool );
|
||||
|
||||
int ii;
|
||||
|
@ -659,7 +659,7 @@ destroyDraw( DrawCtx** dctx )
|
|||
{
|
||||
if ( !!*dctx ) {
|
||||
AndDraw* draw = (AndDraw*)*dctx;
|
||||
JNIEnv* env = *draw->env;
|
||||
JNIEnv* env = ENVFORME( draw->ti );
|
||||
if ( NULL != draw->jdraw ) {
|
||||
(*env)->DeleteGlobalRef( env, draw->jdraw );
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
|
||||
#include "draw.h"
|
||||
|
||||
DrawCtx* makeDraw( MPFORMAL JNIEnv** env, jobject j_draw );
|
||||
#include "andglobals.h"
|
||||
|
||||
DrawCtx* makeDraw( MPFORMAL EnvThreadInfo* ti, jobject j_draw );
|
||||
void destroyDraw( DrawCtx** dctx );
|
||||
|
||||
|
||||
|
|
|
@ -24,17 +24,17 @@
|
|||
|
||||
|
||||
struct JNIUtilCtxt {
|
||||
JNIEnv** envp;
|
||||
EnvThreadInfo* ti;
|
||||
jobject jjniutil;
|
||||
MPSLOT;
|
||||
};
|
||||
|
||||
JNIUtilCtxt*
|
||||
makeJNIUtil( MPFORMAL JNIEnv** envp, jobject jniutls )
|
||||
makeJNIUtil( MPFORMAL EnvThreadInfo* ti, jobject jniutls )
|
||||
{
|
||||
JNIUtilCtxt* ctxt = (JNIUtilCtxt*)XP_CALLOC( mpool, sizeof( *ctxt ) );
|
||||
JNIEnv* env = *envp;
|
||||
ctxt->envp = envp;
|
||||
ctxt->ti = ti;
|
||||
JNIEnv* env = ENVFORME( ti );
|
||||
ctxt->jjniutil = (*env)->NewGlobalRef( env, jniutls );
|
||||
MPASSIGN( ctxt->mpool, mpool );
|
||||
return ctxt;
|
||||
|
@ -45,7 +45,7 @@ destroyJNIUtil( JNIUtilCtxt** ctxtp )
|
|||
{
|
||||
JNIUtilCtxt* ctxt = *ctxtp;
|
||||
if ( !!ctxt ) {
|
||||
JNIEnv* env = *ctxt->envp;
|
||||
JNIEnv* env = ENVFORME( ctxt->ti );
|
||||
(*env)->DeleteGlobalRef( env, ctxt->jjniutil );
|
||||
XP_FREE( ctxt->mpool, ctxt );
|
||||
*ctxtp = NULL;
|
||||
|
@ -59,7 +59,7 @@ and_util_makeJBitmap( JNIUtilCtxt* jniutil, int nCols, int nRows,
|
|||
const jboolean* colors )
|
||||
{
|
||||
jobject bitmap;
|
||||
JNIEnv* env = *jniutil->envp;
|
||||
JNIEnv* env = ENVFORME( jniutil->ti );
|
||||
jmethodID mid
|
||||
= getMethodID( env, jniutil->jjniutil, "makeBitmap",
|
||||
"(II[Z)Landroid/graphics/drawable/BitmapDrawable;" );
|
||||
|
@ -79,7 +79,7 @@ and_util_splitFaces( JNIUtilCtxt* jniutil, const XP_U8* bytes, jsize len,
|
|||
XP_Bool isUTF8 )
|
||||
{
|
||||
jobject strarray = NULL;
|
||||
JNIEnv* env = *jniutil->envp;
|
||||
JNIEnv* env = ENVFORME( jniutil->ti );
|
||||
jmethodID mid
|
||||
= getMethodID( env, jniutil->jjniutil, "splitFaces",
|
||||
"([BZ)[[Ljava/lang/String;" );
|
||||
|
@ -96,7 +96,7 @@ jstring
|
|||
and_util_getMD5SumForDict( JNIUtilCtxt* jniutil, const XP_UCHAR* name,
|
||||
const XP_U8* bytes, jsize len )
|
||||
{
|
||||
JNIEnv* env = *jniutil->envp;
|
||||
JNIEnv* env = ENVFORME( jniutil->ti );
|
||||
jmethodID mid = getMethodID( env, jniutil->jjniutil, "getMD5SumFor",
|
||||
"(Ljava/lang/String;[B)Ljava/lang/String;" );
|
||||
jstring jname = (*env)->NewStringUTF( env, name );
|
||||
|
@ -112,7 +112,7 @@ and_util_getMD5SumForDict( JNIUtilCtxt* jniutil, const XP_UCHAR* name,
|
|||
jstring
|
||||
and_util_getMD5SumForBytes( JNIUtilCtxt* jniutil, const XP_U8* bytes, jsize len )
|
||||
{
|
||||
JNIEnv* env = *jniutil->envp;
|
||||
JNIEnv* env = ENVFORME( jniutil->ti );
|
||||
jmethodID mid = getMethodID( env, jniutil->jjniutil, "getMD5SumFor",
|
||||
"([B)Ljava/lang/String;" );
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
typedef struct JNIUtilCtxt JNIUtilCtxt;
|
||||
|
||||
JNIUtilCtxt* makeJNIUtil( MPFORMAL JNIEnv** env, jobject jniutls );
|
||||
JNIUtilCtxt* makeJNIUtil( MPFORMAL EnvThreadInfo* ti, jobject jniutls );
|
||||
void destroyJNIUtil( JNIUtilCtxt** jniu );
|
||||
|
||||
jobject and_util_makeJBitmap( JNIUtilCtxt* jniu, int nCols, int nRows,
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct _TimerStorage {
|
|||
|
||||
typedef struct _AndUtil {
|
||||
XW_UtilCtxt util;
|
||||
JNIEnv** env;
|
||||
EnvThreadInfo* ti;
|
||||
jobject jutil; /* global ref to object implementing XW_UtilCtxt */
|
||||
TimerStorage timerStorage[NUM_TIMERS_PLUS_ONE];
|
||||
XP_UCHAR* userStrings[N_AND_USER_STRINGS];
|
||||
|
@ -70,7 +70,7 @@ and_util_makeStreamFromAddr( XW_UtilCtxt* uc, XP_PlayerAddr channelNo )
|
|||
|
||||
#define UTIL_CBK_HEADER(nam,sig) \
|
||||
AndUtil* util = (AndUtil*)uc; \
|
||||
JNIEnv* env = *util->env; \
|
||||
JNIEnv* env = ENVFORME( util->ti ); \
|
||||
if ( NULL != util->jutil ) { \
|
||||
jmethodID mid = getMethodID( env, util->jutil, nam, sig )
|
||||
|
||||
|
@ -376,7 +376,7 @@ XP_U32
|
|||
and_util_getCurSeconds( XW_UtilCtxt* uc )
|
||||
{
|
||||
AndUtil* andutil = (AndUtil*)uc;
|
||||
XP_U32 curSeconds = getCurSeconds( *andutil->env );
|
||||
XP_U32 curSeconds = getCurSeconds( ENVFORME( andutil->ti ) );
|
||||
/* struct timeval tv; */
|
||||
/* gettimeofday( &tv, NULL ); */
|
||||
/* XP_LOGF( "%s: %d vs %d", __func__, (int)tv.tv_sec, (int)curSeconds ); */
|
||||
|
@ -394,7 +394,7 @@ and_util_makeEmptyDict( XW_UtilCtxt* uc )
|
|||
AndUtil* andutil = (AndUtil*)uc;
|
||||
DictionaryCtxt* result =
|
||||
and_dictionary_make_empty( MPPARM( ((AndUtil*)uc)->util.mpool )
|
||||
*andutil->env, globals->jniutil );
|
||||
ENVFORME( andutil->ti ), globals->jniutil );
|
||||
return dict_ref( result );
|
||||
#endif
|
||||
}
|
||||
|
@ -637,7 +637,7 @@ static XP_UCHAR*
|
|||
and_util_md5sum( XW_UtilCtxt* uc, const XP_U8* ptr, XP_U16 len )
|
||||
{
|
||||
AndUtil* util = (AndUtil*)uc;
|
||||
JNIEnv* env = *util->env;
|
||||
JNIEnv* env = ENVFORME( util->ti );
|
||||
AndGlobals* globals = (AndGlobals*)uc->closure;
|
||||
struct JNIUtilCtxt* jniutil = globals->jniutil;
|
||||
jstring jsum = and_util_getMD5SumForBytes( jniutil, ptr, len );
|
||||
|
@ -649,13 +649,13 @@ and_util_md5sum( XW_UtilCtxt* uc, const XP_U8* ptr, XP_U16 len )
|
|||
|
||||
|
||||
XW_UtilCtxt*
|
||||
makeUtil( MPFORMAL JNIEnv** envp, jobject jutil, CurGameInfo* gi,
|
||||
makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
|
||||
AndGlobals* closure )
|
||||
{
|
||||
AndUtil* util = (AndUtil*)XP_CALLOC( mpool, sizeof(*util) );
|
||||
UtilVtable* vtable = (UtilVtable*)XP_CALLOC( mpool, sizeof(*vtable) );
|
||||
util->env = envp;
|
||||
JNIEnv* env = *envp;
|
||||
util->ti = ti;
|
||||
JNIEnv* env = ENVFORME( util->ti );
|
||||
if ( NULL != jutil ) {
|
||||
util->jutil = (*env)->NewGlobalRef( env, jutil );
|
||||
}
|
||||
|
@ -743,7 +743,7 @@ void
|
|||
destroyUtil( XW_UtilCtxt** utilc )
|
||||
{
|
||||
AndUtil* util = (AndUtil*)*utilc;
|
||||
JNIEnv *env = *util->env;
|
||||
JNIEnv* env = ENVFORME( util->ti );
|
||||
|
||||
int ii;
|
||||
for ( ii = 0; ii < VSIZE(util->userStrings); ++ii ) {
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "util.h"
|
||||
#include "andglobals.h"
|
||||
|
||||
XW_UtilCtxt* makeUtil( MPFORMAL JNIEnv** env, jobject j_util,
|
||||
XW_UtilCtxt* makeUtil( MPFORMAL EnvThreadInfo* ti, jobject j_util,
|
||||
CurGameInfo* gi, AndGlobals* globals );
|
||||
void destroyUtil( XW_UtilCtxt** util );
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
typedef struct _AndTransportProcs {
|
||||
TransportProcs tp;
|
||||
JNIEnv** envp;
|
||||
EnvThreadInfo* ti;
|
||||
jobject jxport;
|
||||
MPSLOT
|
||||
} AndTransportProcs;
|
||||
|
@ -56,7 +56,7 @@ and_xport_getFlags( void* closure )
|
|||
jint result = 0;
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = *aprocs->envp;
|
||||
JNIEnv* env = ENVFORME( aprocs->ti );
|
||||
const char* sig = "()I";
|
||||
jmethodID mid = getMethodID( env, aprocs->jxport, "getFlags", sig );
|
||||
|
||||
|
@ -73,7 +73,7 @@ and_xport_send( const XP_U8* buf, XP_U16 len, const CommsAddrRec* addr,
|
|||
LOG_FUNC();
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = *aprocs->envp;
|
||||
JNIEnv* env = ENVFORME( aprocs->ti );
|
||||
const char* sig = "([BL" PKG_PATH("jni/CommsAddrRec") ";I)I";
|
||||
jmethodID mid = getMethodID( env, aprocs->jxport, "transportSend", sig );
|
||||
|
||||
|
@ -94,7 +94,7 @@ and_xport_relayStatus( void* closure, CommsRelayState newState )
|
|||
{
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = *aprocs->envp;
|
||||
JNIEnv* env = ENVFORME( aprocs->ti );
|
||||
const char* sig = "(L" PKG_PATH("jni/TransportProcs$CommsRelayState") ";)V";
|
||||
jmethodID mid = getMethodID( env, aprocs->jxport, "relayStatus", sig );
|
||||
|
||||
|
@ -111,7 +111,7 @@ and_xport_relayConnd( void* closure, XP_UCHAR* const room, XP_Bool reconnect,
|
|||
{
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = *aprocs->envp;
|
||||
JNIEnv* env = ENVFORME( aprocs->ti );
|
||||
const char* sig = "(Ljava/lang/String;IZI)V";
|
||||
jmethodID mid = getMethodID( env, aprocs->jxport, "relayConnd", sig );
|
||||
|
||||
|
@ -129,7 +129,7 @@ and_xport_sendNoConn( const XP_U8* buf, XP_U16 len,
|
|||
jboolean result = false;
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
if ( NULL != aprocs && NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = *aprocs->envp;
|
||||
JNIEnv* env = ENVFORME( aprocs->ti );
|
||||
|
||||
const char* sig = "([BLjava/lang/String;)Z";
|
||||
jmethodID mid = getMethodID( env, aprocs->jxport,
|
||||
|
@ -148,7 +148,7 @@ and_xport_relayError( void* closure, XWREASON relayErr )
|
|||
{
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = *aprocs->envp;
|
||||
JNIEnv* env = ENVFORME( aprocs->ti );
|
||||
jmethodID mid;
|
||||
const char* sig =
|
||||
"(L" PKG_PATH("jni/TransportProcs$XWRELAY_ERROR") ";)V";
|
||||
|
@ -163,16 +163,16 @@ and_xport_relayError( void* closure, XWREASON relayErr )
|
|||
}
|
||||
|
||||
TransportProcs*
|
||||
makeXportProcs( MPFORMAL JNIEnv** envp, jobject jxport )
|
||||
makeXportProcs( MPFORMAL EnvThreadInfo* ti, jobject jxport )
|
||||
{
|
||||
AndTransportProcs* aprocs = NULL;
|
||||
|
||||
JNIEnv* env = *envp;
|
||||
JNIEnv* env = ENVFORME( ti );
|
||||
aprocs = (AndTransportProcs*)XP_CALLOC( mpool, sizeof(*aprocs) );
|
||||
if ( NULL != jxport ) {
|
||||
aprocs->jxport = (*env)->NewGlobalRef( env, jxport );
|
||||
}
|
||||
aprocs->envp = envp;
|
||||
aprocs->ti = ti;
|
||||
MPASSIGN( aprocs->mpool, mpool );
|
||||
|
||||
#ifdef COMMS_XPORT_FLAGSPROC
|
||||
|
@ -192,7 +192,7 @@ void
|
|||
destroyXportProcs( TransportProcs** xport )
|
||||
{
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)*xport;
|
||||
JNIEnv* env = *aprocs->envp;
|
||||
JNIEnv* env = ENVFORME( aprocs->ti );
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
(*env)->DeleteGlobalRef( env, aprocs->jxport );
|
||||
}
|
||||
|
|
|
@ -23,9 +23,12 @@
|
|||
|
||||
#include <jni.h>
|
||||
|
||||
#include "andglobals.h"
|
||||
|
||||
#include "comms.h"
|
||||
|
||||
TransportProcs* makeXportProcs( MPFORMAL JNIEnv** env, jobject jxport );
|
||||
TransportProcs* makeXportProcs( MPFORMAL EnvThreadInfo* ti, jobject jxport );
|
||||
|
||||
void destroyXportProcs( TransportProcs** xport );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
|
@ -37,16 +38,97 @@
|
|||
#include "xportwrapper.h"
|
||||
#include "anddict.h"
|
||||
#include "andutils.h"
|
||||
#include "andglobals.h"
|
||||
#include "jniutlswrapper.h"
|
||||
#include "paths.h"
|
||||
|
||||
typedef struct _EnvThreadEntry {
|
||||
JNIEnv* env;
|
||||
pthread_t owner;
|
||||
} EnvThreadEntry;
|
||||
|
||||
#define MAX_ENV_THREADS 10
|
||||
|
||||
struct _EnvThreadInfo {
|
||||
pthread_mutex_t mtxThreads;
|
||||
EnvThreadEntry entries[MAX_ENV_THREADS];
|
||||
XP_U16 nMaps;
|
||||
};
|
||||
|
||||
/* Globals for the whole game */
|
||||
typedef struct _JNIGlobalState {
|
||||
JNIEnv* env;
|
||||
EnvThreadInfo ti;
|
||||
DictMgrCtxt* dictMgr;
|
||||
MPSLOT
|
||||
} JNIGlobalState;
|
||||
|
||||
static void
|
||||
map_init( EnvThreadInfo* ti )
|
||||
{
|
||||
pthread_mutex_init( &ti->mtxThreads, NULL );
|
||||
}
|
||||
|
||||
static void
|
||||
map_destroy( EnvThreadInfo* ti )
|
||||
{
|
||||
// XP_ASSERT( 0 == ti->nMaps );
|
||||
XP_LOGF( "%s: had %d threads max", __func__, ti->nMaps );
|
||||
pthread_mutex_destroy( &ti->mtxThreads );
|
||||
}
|
||||
|
||||
static void
|
||||
map_thread( EnvThreadInfo* ti, JNIEnv* env, const char* proc )
|
||||
{
|
||||
pthread_t self = pthread_self();
|
||||
|
||||
pthread_mutex_lock( &ti->mtxThreads );
|
||||
|
||||
XP_Bool found = false;
|
||||
for ( int ii = 0; !found && ii < ti->nMaps; ++ii ) {
|
||||
EnvThreadEntry* entry = &ti->entries[ii];
|
||||
found = self == entry->owner;
|
||||
if ( found ) {
|
||||
if ( env != entry->env ) {
|
||||
/* this DOES happen!!! */
|
||||
XP_LOGF( "%s: replacing env %p with env %p for thread %x",
|
||||
__func__, entry->env, env, (int)self );
|
||||
entry->env = env;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found ) {
|
||||
EnvThreadEntry* entry = &ti->entries[ti->nMaps++];
|
||||
entry->owner = self;
|
||||
entry->env = env;
|
||||
XP_LOGF( "%s: mapped env %p to thread %x", __func__, env, (int)self );
|
||||
XP_ASSERT( ti->nMaps < MAX_ENV_THREADS );
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &ti->mtxThreads );
|
||||
}
|
||||
|
||||
JNIEnv*
|
||||
envForMe( EnvThreadInfo* ti, const char* caller )
|
||||
{
|
||||
JNIEnv* result = NULL;
|
||||
pthread_t self = pthread_self();
|
||||
pthread_mutex_lock( &ti->mtxThreads );
|
||||
for ( int ii = 0; ii < ti->nMaps; ++ii ) {
|
||||
if ( self == ti->entries[ii].owner ) {
|
||||
result = ti->entries[ii].env;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock( &ti->mtxThreads );
|
||||
if( !result ) {
|
||||
XP_LOGF( "no env for %s (thread %x in %d entries)", caller,
|
||||
(int)self, ti->nMaps );
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_initGlobals
|
||||
( JNIEnv* env, jclass C )
|
||||
|
@ -55,7 +137,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_initGlobals
|
|||
MemPoolCtx* mpool = mpool_make();
|
||||
#endif
|
||||
JNIGlobalState* state = (JNIGlobalState*)XP_CALLOC( mpool, sizeof(*state) );
|
||||
state->env = env;
|
||||
map_init( &state->ti );
|
||||
state->dictMgr = dmgr_make( MPPARM_NOCOMMA( mpool ) );
|
||||
MPASSIGN( state->mpool, mpool );
|
||||
LOG_RETURNF( "%p", state );
|
||||
|
@ -69,11 +151,12 @@ Java_org_eehouse_android_xw4_jni_XwJNI_cleanGlobals
|
|||
LOG_FUNC();
|
||||
if ( 0 != ptr ) {
|
||||
JNIGlobalState* state = (JNIGlobalState*)ptr;
|
||||
XP_ASSERT( state->env == env );
|
||||
XP_ASSERT( ENVFORME(&state->ti) == env );
|
||||
dmgr_destroy( state->dictMgr );
|
||||
#ifdef MEM_DEBUG
|
||||
MemPoolCtx* mpool = state->mpool;
|
||||
#endif
|
||||
map_destroy( &state->ti );
|
||||
XP_FREE( mpool, state );
|
||||
mpool_destroy( mpool );
|
||||
}
|
||||
|
@ -386,9 +469,10 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo
|
|||
{
|
||||
jboolean result = false;
|
||||
JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr;
|
||||
JNIUtilCtxt* jniutil = makeJNIUtil( MPPARM(state->mpool) &env, jniu );
|
||||
JNIUtilCtxt* jniutil = makeJNIUtil( MPPARM(state->mpool) &state->ti, jniu );
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(state->mpool) env, state->dictMgr,
|
||||
jniutil, jname, jDictBytes, jpath, NULL, check );
|
||||
jniutil, jname, jDictBytes, jpath,
|
||||
NULL, check );
|
||||
if ( NULL != dict ) {
|
||||
if ( NULL != jinfo ) {
|
||||
XP_LangCode code = dict_getLangCode( dict );
|
||||
|
@ -435,9 +519,8 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getTileValue
|
|||
return dict_getTileValue( (DictionaryCtxt*)dictPtr, tile );
|
||||
}
|
||||
|
||||
typedef struct _JNIState {
|
||||
struct _JNIState {
|
||||
XWGame game;
|
||||
JNIEnv* env;
|
||||
JNIGlobalState* globalJNI;
|
||||
AndGlobals globals;
|
||||
XP_U16 curSaveCount;
|
||||
|
@ -446,38 +529,22 @@ typedef struct _JNIState {
|
|||
const char* envSetterFunc;
|
||||
#endif
|
||||
MPSLOT
|
||||
} JNIState;
|
||||
|
||||
#ifdef DEBUG
|
||||
# define CHECK_ENV() \
|
||||
if ( state->env != 0 && state->env != env ) { \
|
||||
XP_LOGF( "ERROR: %s trying to set env when %s still has it", \
|
||||
__func__, state->envSetterFunc ); \
|
||||
XP_ASSERT( state->env == 0 || state->env == env ); \
|
||||
} \
|
||||
state->envSetterFunc = __func__; \
|
||||
|
||||
#else
|
||||
# define CHECK_ENV()
|
||||
#endif
|
||||
};
|
||||
|
||||
#define XWJNI_START() { \
|
||||
XP_ASSERT( 0 != gamePtr ); \
|
||||
JNIState* state = (JNIState*)gamePtr; \
|
||||
MPSLOT; \
|
||||
MPASSIGN( mpool, state->mpool); \
|
||||
/* if reentrant must be from same thread */ \
|
||||
CHECK_ENV(); \
|
||||
JNIEnv* _oldEnv = state->env; \
|
||||
state->env = env;
|
||||
XP_ASSERT( !!state->globalJNI ); \
|
||||
map_thread( &state->globalJNI->ti, env, __func__ ); \
|
||||
|
||||
#define XWJNI_START_GLOBALS() \
|
||||
XWJNI_START() \
|
||||
AndGlobals* globals = &state->globals; \
|
||||
|
||||
#define XWJNI_END() \
|
||||
state->env = _oldEnv; \
|
||||
}
|
||||
#define XWJNI_END() \
|
||||
} \
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_initJNI
|
||||
|
@ -493,7 +560,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_initJNI
|
|||
JNIState* state = (JNIState*)XP_CALLOC( mpool, sizeof(*state) );
|
||||
state->globalJNI = (JNIGlobalState*)jniGlobalPtr;
|
||||
AndGlobals* globals = &state->globals;
|
||||
globals->state = (struct JNIState*)state;
|
||||
globals->state = (JNIState*)state;
|
||||
MPASSIGN( state->mpool, mpool );
|
||||
globals->vtMgr = make_vtablemgr(MPPARM_NOCOMMA(mpool));
|
||||
|
||||
|
@ -511,17 +578,18 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
|||
jstring j_lang )
|
||||
{
|
||||
XWJNI_START_GLOBALS();
|
||||
EnvThreadInfo* ti = &state->globalJNI->ti;
|
||||
CurGameInfo* gi = makeGI( MPPARM(mpool) env, j_gi );
|
||||
globals->gi = gi;
|
||||
globals->util = makeUtil( MPPARM(mpool) &state->env, j_util, gi,
|
||||
globals->util = makeUtil( MPPARM(mpool) ti, j_util, gi,
|
||||
globals );
|
||||
globals->jniutil = makeJNIUtil( MPPARM(mpool) &state->env, jniu );
|
||||
globals->jniutil = makeJNIUtil( MPPARM(mpool) ti, jniu );
|
||||
DrawCtx* dctx = NULL;
|
||||
if ( !!j_draw ) {
|
||||
dctx = makeDraw( MPPARM(mpool) &state->env, j_draw );
|
||||
dctx = makeDraw( MPPARM(mpool) ti, j_draw );
|
||||
}
|
||||
globals->dctx = dctx;
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) &state->env, j_procs );
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) ti, j_procs );
|
||||
CommonPrefs cp;
|
||||
loadCommonPrefs( env, &cp, j_cp );
|
||||
|
||||
|
@ -559,8 +627,6 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
|
|||
|
||||
destroyGI( MPPARM(mpool) &globals->gi );
|
||||
|
||||
JNIEnv* oldEnv = state->env;
|
||||
state->env = env;
|
||||
game_dispose( &state->game );
|
||||
|
||||
destroyDraw( &globals->dctx );
|
||||
|
@ -569,7 +635,6 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
|
|||
destroyJNIUtil( &globals->jniutil );
|
||||
vtmgr_destroy( MPPARM(mpool) globals->vtMgr );
|
||||
|
||||
state->env = oldEnv;
|
||||
XP_FREE( mpool, state );
|
||||
mpool_destroy( mpool );
|
||||
} /* game_dispose */
|
||||
|
@ -585,18 +650,18 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
|
|||
DictionaryCtxt* dict;
|
||||
PlayerDicts dicts;
|
||||
XWJNI_START_GLOBALS();
|
||||
EnvThreadInfo* ti = &state->globalJNI->ti;
|
||||
|
||||
globals->gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*globals->gi) );
|
||||
globals->util = makeUtil( MPPARM(mpool) &state->env,
|
||||
jutil, globals->gi, globals );
|
||||
globals->jniutil = makeJNIUtil( MPPARM(mpool) &state->env, jniu );
|
||||
globals->util = makeUtil( MPPARM(mpool) ti, jutil, globals->gi, globals);
|
||||
globals->jniutil = makeJNIUtil( MPPARM(mpool) ti, jniu );
|
||||
makeDicts( MPPARM(state->globalJNI->mpool) env, state->globalJNI->dictMgr,
|
||||
globals->jniutil, &dict, &dicts, jdictNames, jdicts, jpaths,
|
||||
jlang );
|
||||
if ( !!jdraw ) {
|
||||
globals->dctx = makeDraw( MPPARM(mpool) &state->env, jdraw );
|
||||
globals->dctx = makeDraw( MPPARM(mpool) ti, jdraw );
|
||||
}
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) &state->env, jprocs );
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) ti, jprocs );
|
||||
|
||||
XWStreamCtxt* stream = streamFromJStream( MPPARM(mpool) env,
|
||||
globals->vtMgr, jstream );
|
||||
|
@ -673,7 +738,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setDraw
|
|||
{
|
||||
XWJNI_START_GLOBALS();
|
||||
|
||||
DrawCtx* newDraw = makeDraw( MPPARM(mpool) &state->env, jdraw );
|
||||
DrawCtx* newDraw = makeDraw( MPPARM(mpool) &state->globalJNI->ti, jdraw );
|
||||
board_setDraw( state->game.board, newDraw );
|
||||
|
||||
destroyDraw( &globals->dctx );
|
||||
|
@ -1664,7 +1729,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1iter_1init
|
|||
JNIGlobalState* state = (JNIGlobalState*)jniGlobalPtr;
|
||||
DictIterData* data = XP_CALLOC( state->mpool, sizeof(*data) );
|
||||
data->env = env;
|
||||
JNIUtilCtxt* jniutil = makeJNIUtil( MPPARM(state->mpool) &data->env, jniu );
|
||||
JNIUtilCtxt* jniutil = makeJNIUtil( MPPARM(state->mpool) &state->ti, jniu );
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(state->mpool) env, state->dictMgr,
|
||||
jniutil, jname, jDictBytes, jpath, NULL,
|
||||
false );
|
||||
|
|
Loading…
Add table
Reference in a new issue