mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-29 08:34:37 +01:00
retain thread->env mapping in DEBUG builds only
I'm keeping it AND asserting at every possible location that the env passed all the way in is the same as what the mapping produces. If in months I haven't seen a single crash then I can evaluate which way of passing the env around is better. (It'd be code size vs. performance, as the passing of env is noticably faster. Code size could be fixed by turning 'XWEnv xwe,' into a macro that goes away on some builds.)
This commit is contained in:
parent
88335d38f2
commit
9fa23af6e0
12 changed files with 224 additions and 71 deletions
|
@ -37,6 +37,9 @@
|
|||
|
||||
typedef struct _AndDictionaryCtxt {
|
||||
DictionaryCtxt super;
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti;
|
||||
#endif
|
||||
JNIUtilCtxt* jniutil;
|
||||
off_t bytesSize;
|
||||
jbyte* bytes;
|
||||
|
@ -61,6 +64,7 @@ dict_splitFaces( DictionaryCtxt* dict, XWEnv xwe, const XP_U8* bytes,
|
|||
XP_U16 nBytes, XP_U16 nFaces )
|
||||
{
|
||||
AndDictionaryCtxt* ctxt = (AndDictionaryCtxt*)dict;
|
||||
ASSERT_ENV( ctxt->ti, xwe );
|
||||
splitFaces_via_java( xwe, ctxt, bytes, nBytes, nFaces,
|
||||
dict->isUTF8 );
|
||||
}
|
||||
|
@ -304,6 +308,7 @@ parseDict( AndDictionaryCtxt* ctxt, XWEnv xwe, XP_U8 const* ptr,
|
|||
{
|
||||
XP_Bool success = XP_TRUE;
|
||||
XP_ASSERT( !!ptr );
|
||||
ASSERT_ENV( ctxt->ti, xwe );
|
||||
const XP_U8* end = ptr + dictLength;
|
||||
XP_U32 offset;
|
||||
XP_U16 nFaces, numFaceBytes = 0;
|
||||
|
@ -482,6 +487,7 @@ static void
|
|||
and_dictionary_destroy( DictionaryCtxt* dict, XWEnv xwe )
|
||||
{
|
||||
AndDictionaryCtxt* ctxt = (AndDictionaryCtxt*)dict;
|
||||
ASSERT_ENV( ctxt->ti, xwe );
|
||||
XP_LOGF( "%s(dict=%p); code=%x", __func__, ctxt, ctxt->dbgid );
|
||||
XP_U16 nSpecials = andCountSpecials( ctxt );
|
||||
JNIEnv* env = xwe;
|
||||
|
@ -561,7 +567,11 @@ and_dictionary_make_empty( MPFORMAL JNIUtilCtxt* jniutil )
|
|||
}
|
||||
|
||||
void
|
||||
makeDicts( MPFORMAL JNIEnv *env, DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil,
|
||||
makeDicts( MPFORMAL JNIEnv *env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil,
|
||||
DictionaryCtxt** dictp, PlayerDicts* dicts,
|
||||
jobjectArray jnames, jobjectArray jdicts, jobjectArray jpaths,
|
||||
jstring jlang )
|
||||
|
@ -577,8 +587,8 @@ makeDicts( MPFORMAL JNIEnv *env, DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil,
|
|||
NULL : (*env)->GetObjectArrayElement( env, jpaths, ii );
|
||||
if ( NULL != jdict || NULL != jpath ) {
|
||||
jstring jname = (*env)->GetObjectArrayElement( env, jnames, ii );
|
||||
dict = makeDict( MPPARM(mpool) env, dictMgr, jniutil, jname, jdict,
|
||||
jpath, jlang, false );
|
||||
dict = makeDict( MPPARM(mpool) env, TI_IF(ti) dictMgr, jniutil,
|
||||
jname, jdict, jpath, jlang, false );
|
||||
XP_ASSERT( !!dict );
|
||||
deleteLocalRefs( env, jdict, jname, DELETE_NO_REF );
|
||||
}
|
||||
|
@ -594,8 +604,12 @@ makeDicts( MPFORMAL JNIEnv *env, DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil,
|
|||
}
|
||||
|
||||
DictionaryCtxt*
|
||||
makeDict( MPFORMAL JNIEnv *env, DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil,
|
||||
jstring jname, jbyteArray jbytes, jstring jpath, jstring jlangname, jboolean check )
|
||||
makeDict( MPFORMAL JNIEnv *env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil, jstring jname,
|
||||
jbyteArray jbytes, jstring jpath, jstring jlangname, jboolean check )
|
||||
{
|
||||
jbyte* bytes = NULL;
|
||||
jbyteArray byteArray = NULL;
|
||||
|
@ -633,6 +647,9 @@ makeDict( MPFORMAL JNIEnv *env, DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil,
|
|||
if ( NULL != bytes ) {
|
||||
anddict = (AndDictionaryCtxt*)
|
||||
and_dictionary_make_empty( MPPARM(mpool) jniutil );
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
anddict->ti = ti;
|
||||
#endif
|
||||
anddict->bytes = bytes;
|
||||
anddict->byteArray = byteArray;
|
||||
anddict->bytesSize = bytesSize;
|
||||
|
|
|
@ -30,11 +30,19 @@ void
|
|||
dict_splitFaces( DictionaryCtxt* dict, XWEnv xwe, const XP_U8* bytes,
|
||||
XP_U16 nBytes, XP_U16 nFaces );
|
||||
|
||||
DictionaryCtxt* makeDict( MPFORMAL JNIEnv *env, DictMgrCtxt* dictMgr,
|
||||
JNIUtilCtxt* jniutil, jstring jname, jbyteArray bytes,
|
||||
DictionaryCtxt* makeDict( MPFORMAL JNIEnv *env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil,
|
||||
jstring jname, jbyteArray bytes,
|
||||
jstring path, jstring jlang, jboolean check );
|
||||
|
||||
void makeDicts( MPFORMAL JNIEnv *env, DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil,
|
||||
void makeDicts( MPFORMAL JNIEnv *env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil,
|
||||
DictionaryCtxt** dict, PlayerDicts* dicts, jobjectArray jnames,
|
||||
jobjectArray jdicts, jobjectArray jpaths, jstring jlang );
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
|
||||
typedef struct _JNIState JNIState;
|
||||
|
||||
#ifdef DEBUG
|
||||
# define MAP_THREAD_TO_ENV
|
||||
#endif
|
||||
|
||||
typedef struct _AndGameGlobals {
|
||||
VTableMgr* vtMgr;
|
||||
CurGameInfo* gi;
|
||||
|
@ -39,7 +43,14 @@ typedef struct _AndGameGlobals {
|
|||
|
||||
typedef struct _EnvThreadInfo EnvThreadInfo;
|
||||
|
||||
# ifdef MAP_THREAD_TO_ENV
|
||||
JNIEnv* envForMe( EnvThreadInfo* ti, const char* caller );
|
||||
#define ENVFORME( ti ) envForMe( (ti), __func__ )
|
||||
# define ENVFORME( ti ) envForMe( (ti), __func__ )
|
||||
# define ASSERT_ENV(TI, ENV) XP_ASSERT( ENVFORME(TI) == ENV )
|
||||
# define TI_IF(tip) (tip),
|
||||
# else
|
||||
# define ASSERT_ENV(TI, ENV)
|
||||
# define TI_IF(tip)
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,9 @@ enum {
|
|||
|
||||
typedef struct _AndDraw {
|
||||
DrawCtxVTable* vtable;
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti;
|
||||
#endif
|
||||
jobject jdraw; /* global ref; free it! */
|
||||
XP_LangCode curLang;
|
||||
jobject jCache[JCACHE_COUNT];
|
||||
|
@ -210,6 +213,7 @@ makeDSI( AndDraw* draw, XWEnv xwe, int indx, const DrawScoreInfo* dsi )
|
|||
#define DRAW_CBK_HEADER(nam,sig) \
|
||||
JNIEnv* env = xwe; \
|
||||
AndDraw* draw = (AndDraw*)dctx; \
|
||||
ASSERT_ENV( draw->ti, env ); \
|
||||
XP_ASSERT( !!draw->jdraw ); \
|
||||
jmethodID mid = getMethodID( xwe, draw->jdraw, nam, sig );
|
||||
|
||||
|
@ -648,9 +652,16 @@ draw_doNothing( DrawCtx* dctx, XWEnv xwe, ... )
|
|||
} /* draw_doNothing */
|
||||
|
||||
DrawCtx*
|
||||
makeDraw( MPFORMAL JNIEnv* env, jobject jdraw )
|
||||
makeDraw( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject jdraw )
|
||||
{
|
||||
AndDraw* draw = (AndDraw*)XP_CALLOC( mpool, sizeof(*draw) );
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
draw->ti = ti;
|
||||
#endif
|
||||
draw->vtable = XP_MALLOC( mpool, sizeof(*draw->vtable) );
|
||||
if ( NULL != jdraw ) {
|
||||
draw->jdraw = (*env)->NewGlobalRef( env, jdraw );
|
||||
|
|
|
@ -27,7 +27,11 @@
|
|||
|
||||
#include "andglobals.h"
|
||||
|
||||
DrawCtx* makeDraw( MPFORMAL JNIEnv* env, jobject j_draw );
|
||||
DrawCtx* makeDraw( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject j_draw );
|
||||
void destroyDraw( DrawCtx** dctx, JNIEnv* env );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,16 +24,24 @@
|
|||
|
||||
|
||||
struct JNIUtilCtxt {
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti;
|
||||
#endif
|
||||
jobject jjniutil;
|
||||
MPSLOT;
|
||||
};
|
||||
|
||||
JNIUtilCtxt*
|
||||
makeJNIUtil( MPFORMAL JNIEnv* env, EnvThreadInfo* ti, jobject jniutls )
|
||||
makeJNIUtil( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject jniutls )
|
||||
{
|
||||
JNIUtilCtxt* ctxt = (JNIUtilCtxt*)XP_CALLOC( mpool, sizeof( *ctxt ) );
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
ctxt->ti = ti;
|
||||
#endif
|
||||
ctxt->jjniutil = (*env)->NewGlobalRef( env, jniutls );
|
||||
MPASSIGN( ctxt->mpool, mpool );
|
||||
return ctxt;
|
||||
|
|
|
@ -28,7 +28,10 @@
|
|||
|
||||
typedef struct JNIUtilCtxt JNIUtilCtxt;
|
||||
|
||||
JNIUtilCtxt* makeJNIUtil( MPFORMAL JNIEnv* env, EnvThreadInfo* ti,
|
||||
JNIUtilCtxt* makeJNIUtil( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject jniutls );
|
||||
void destroyJNIUtil( JNIEnv* env, JNIUtilCtxt** jniu );
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@ typedef struct _AndDUtil {
|
|||
jobject jdutil; /* global ref to object implementing XW_DUtilCtxt */
|
||||
XP_UCHAR* userStrings[N_AND_USER_STRINGS];
|
||||
XP_U32 userStringsBits;
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti;
|
||||
#endif
|
||||
#ifdef XWFEATURE_DEVID
|
||||
XP_UCHAR* devIDStorage;
|
||||
#endif
|
||||
|
@ -49,6 +52,9 @@ typedef struct _TimerStorage {
|
|||
|
||||
typedef struct _AndUtil {
|
||||
XW_UtilCtxt util;
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti;
|
||||
#endif
|
||||
jobject jutil; /* global ref to object implementing XW_UtilCtxt */
|
||||
TimerStorage timerStorage[NUM_TIMERS_PLUS_ONE];
|
||||
} AndUtil;
|
||||
|
@ -73,6 +79,7 @@ and_util_makeStreamFromAddr( XW_UtilCtxt* uc, XWEnv XP_UNUSED(xwe),
|
|||
#define UTIL_CBK_HEADER(nam,sig) \
|
||||
AndUtil* util = (AndUtil*)uc; \
|
||||
JNIEnv* env = xwe; \
|
||||
ASSERT_ENV(util->ti, env); \
|
||||
if ( NULL != util->jutil ) { \
|
||||
jmethodID mid = getMethodID( env, util->jutil, nam, sig )
|
||||
|
||||
|
@ -85,6 +92,7 @@ and_util_makeStreamFromAddr( XW_UtilCtxt* uc, XWEnv XP_UNUSED(xwe),
|
|||
#define DUTIL_CBK_HEADER(nam,sig) \
|
||||
AndDUtil* dutil = (AndDUtil*)duc; \
|
||||
JNIEnv* env = xwe; \
|
||||
ASSERT_ENV(dutil->ti, env); \
|
||||
if ( NULL != dutil->jdutil ) { \
|
||||
jmethodID mid = getMethodID( env, dutil->jdutil, nam, sig )
|
||||
|
||||
|
@ -840,10 +848,17 @@ and_dutil_onDupTimerChanged( XW_DUtilCtxt* duc, XWEnv xwe, XP_U32 gameID,
|
|||
}
|
||||
|
||||
XW_UtilCtxt*
|
||||
makeUtil( MPFORMAL JNIEnv* env, jobject jutil, CurGameInfo* gi,
|
||||
makeUtil( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject jutil, CurGameInfo* gi,
|
||||
AndGameGlobals* closure )
|
||||
{
|
||||
AndUtil* util = (AndUtil*)XP_CALLOC( mpool, sizeof(*util) );
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
util->ti = ti;
|
||||
#endif
|
||||
UtilVtable* vtable = (UtilVtable*)XP_CALLOC( mpool, sizeof(*vtable) );
|
||||
if ( NULL != jutil ) {
|
||||
util->jutil = (*env)->NewGlobalRef( env, jutil );
|
||||
|
@ -936,10 +951,17 @@ destroyUtil( XW_UtilCtxt** utilc, JNIEnv* env )
|
|||
}
|
||||
|
||||
XW_DUtilCtxt*
|
||||
makeDUtil( MPFORMAL JNIEnv* env, jobject jdutil, VTableMgr* vtMgr,
|
||||
makeDUtil( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject jdutil, VTableMgr* vtMgr,
|
||||
JNIUtilCtxt* jniutil, void* closure )
|
||||
{
|
||||
AndDUtil* dutil = (AndDUtil*)XP_CALLOC( mpool, sizeof(*dutil) );
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
dutil->ti = ti;
|
||||
#endif
|
||||
dutil->jniutil = jniutil;
|
||||
dutil->dutil.closure = closure;
|
||||
dutil->dutil.vtMgr = vtMgr;
|
||||
|
|
|
@ -29,12 +29,19 @@
|
|||
#include "andglobals.h"
|
||||
#include "jniutlswrapper.h"
|
||||
|
||||
XW_DUtilCtxt* makeDUtil( MPFORMAL JNIEnv* env, jobject j_dutil,
|
||||
VTableMgr* vtMgr, JNIUtilCtxt* jniutil,
|
||||
void* closure );
|
||||
XW_DUtilCtxt* makeDUtil( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject j_dutil, VTableMgr* vtMgr,
|
||||
JNIUtilCtxt* jniutil, void* closure );
|
||||
void destroyDUtil( XW_DUtilCtxt** dutilp, JNIEnv* env );
|
||||
|
||||
XW_UtilCtxt* makeUtil( MPFORMAL JNIEnv* env, jobject j_util,
|
||||
XW_UtilCtxt* makeUtil( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject j_util,
|
||||
CurGameInfo* gi, AndGameGlobals* globals );
|
||||
void destroyUtil( XW_UtilCtxt** util, JNIEnv* env );
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
typedef struct _AndTransportProcs {
|
||||
TransportProcs tp;
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti;
|
||||
#endif
|
||||
jobject jxport;
|
||||
MPSLOT
|
||||
} AndTransportProcs;
|
||||
|
@ -55,6 +58,7 @@ and_xport_getFlags( XWEnv xwe, void* closure )
|
|||
{
|
||||
jint result = COMMS_XPORT_FLAGS_NONE;
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
ASSERT_ENV( aprocs->ti, xwe );
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = xwe;
|
||||
const char* sig = "()I";
|
||||
|
@ -73,6 +77,7 @@ and_xport_send( XWEnv xwe, const XP_U8* buf, XP_U16 len,
|
|||
jint result = -1;
|
||||
LOG_FUNC();
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
ASSERT_ENV( aprocs->ti, xwe );
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = xwe;
|
||||
const char* sig = "([BLjava/lang/String;L" PKG_PATH("jni/CommsAddrRec")
|
||||
|
@ -111,6 +116,7 @@ and_xport_relayConnd( XWEnv xwe, void* closure, XP_UCHAR* const room,
|
|||
XP_U16 nMissing )
|
||||
{
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
ASSERT_ENV( aprocs->ti, xwe );
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = xwe;
|
||||
const char* sig = "(Ljava/lang/String;IZI)V";
|
||||
|
@ -130,6 +136,7 @@ and_xport_sendNoConn( XWEnv xwe, const XP_U8* buf, XP_U16 len,
|
|||
{
|
||||
jboolean result = false;
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
ASSERT_ENV( aprocs->ti, xwe );
|
||||
if ( NULL != aprocs && NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = xwe;
|
||||
|
||||
|
@ -151,6 +158,7 @@ static void
|
|||
and_xport_countChanged( XWEnv xwe, void* closure, XP_U16 count )
|
||||
{
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
ASSERT_ENV( aprocs->ti, xwe );
|
||||
if ( NULL != aprocs && NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = xwe;
|
||||
const char* sig = "(I)V";
|
||||
|
@ -163,6 +171,7 @@ static void
|
|||
and_xport_relayError( XWEnv xwe, void* closure, XWREASON relayErr )
|
||||
{
|
||||
AndTransportProcs* aprocs = (AndTransportProcs*)closure;
|
||||
ASSERT_ENV( aprocs->ti, xwe );
|
||||
if ( NULL != aprocs->jxport ) {
|
||||
JNIEnv* env = xwe;
|
||||
jmethodID mid;
|
||||
|
@ -179,11 +188,18 @@ and_xport_relayError( XWEnv xwe, void* closure, XWREASON relayErr )
|
|||
}
|
||||
|
||||
TransportProcs*
|
||||
makeXportProcs( MPFORMAL JNIEnv* env, jobject jxport )
|
||||
makeXportProcs( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject jxport )
|
||||
{
|
||||
AndTransportProcs* aprocs = NULL;
|
||||
|
||||
aprocs = (AndTransportProcs*)XP_CALLOC( mpool, sizeof(*aprocs) );
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
aprocs->ti = ti;
|
||||
#endif
|
||||
if ( NULL != jxport ) {
|
||||
aprocs->jxport = (*env)->NewGlobalRef( env, jxport );
|
||||
}
|
||||
|
|
|
@ -27,7 +27,11 @@
|
|||
|
||||
#include "comms.h"
|
||||
|
||||
TransportProcs* makeXportProcs( MPFORMAL JNIEnv* env, jobject jxport );
|
||||
TransportProcs* makeXportProcs( MPFORMAL JNIEnv* env,
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo* ti,
|
||||
#endif
|
||||
jobject jxport );
|
||||
|
||||
void destroyXportProcs( TransportProcs** xport, JNIEnv* env );
|
||||
|
||||
|
|
|
@ -45,9 +45,12 @@
|
|||
#include "jniutlswrapper.h"
|
||||
#include "paths.h"
|
||||
|
||||
#define LOG_MAPPING
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
# define LOG_MAPPING
|
||||
#endif
|
||||
// #define LOG_MAPPING_ALL
|
||||
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
typedef struct _EnvThreadEntry {
|
||||
JNIEnv* env;
|
||||
pthread_t owner;
|
||||
|
@ -64,9 +67,13 @@ struct _EnvThreadInfo {
|
|||
MPSLOT
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* Globals for the whole game */
|
||||
typedef struct _JNIGlobalState {
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
EnvThreadInfo ti;
|
||||
#endif
|
||||
DictMgrCtxt* dictMgr;
|
||||
SMSProto* smsProto;
|
||||
VTableMgr* vtMgr;
|
||||
|
@ -134,7 +141,8 @@ countUsed( const EnvThreadInfo* ti )
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#define MAP_THREAD( ti, env ) map_thread_prv( (ti), (env), __func__ )
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
# define MAP_THREAD( ti, env ) map_thread_prv( (ti), (env), __func__ )
|
||||
|
||||
static void
|
||||
map_thread_prv( EnvThreadInfo* ti, JNIEnv* env, const char* caller )
|
||||
|
@ -257,7 +265,14 @@ prvEnvForMe( EnvThreadInfo* ti )
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#else
|
||||
# define MAP_THREAD( ti, env )
|
||||
# define MAP_REMOVE( ti, env )
|
||||
# define map_init( ... )
|
||||
# define map_destroy( ti )
|
||||
#endif // MAP_THREAD_TO_ENV
|
||||
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
static pthread_mutex_t g_globalStateLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static JNIGlobalState* g_globalState = NULL;
|
||||
|
||||
|
@ -268,35 +283,6 @@ void setGlobalState( JNIGlobalState* state )
|
|||
pthread_mutex_unlock( &g_globalStateLock );
|
||||
}
|
||||
|
||||
JNIEnv*
|
||||
waitEnvFromGlobals() /* hanging */
|
||||
{
|
||||
JNIEnv* result = NULL;
|
||||
pthread_mutex_lock( &g_globalStateLock );
|
||||
JNIGlobalState* state = g_globalState;
|
||||
if ( !!state ) {
|
||||
result = prvEnvForMe( &state->ti );
|
||||
}
|
||||
if ( !result ) {
|
||||
pthread_mutex_unlock( &g_globalStateLock );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
releaseEnvFromGlobals( JNIEnv* env )
|
||||
{
|
||||
XP_ASSERT( !!env );
|
||||
JNIGlobalState* state = g_globalState;
|
||||
XP_ASSERT( !!state );
|
||||
XP_ASSERT( env == prvEnvForMe( &state->ti ) );
|
||||
pthread_mutex_unlock( &g_globalStateLock );
|
||||
}
|
||||
|
||||
#else
|
||||
# define setGlobalState(s)
|
||||
#endif
|
||||
|
||||
JNIEnv*
|
||||
envForMe( EnvThreadInfo* ti, const char* caller )
|
||||
{
|
||||
|
@ -311,6 +297,39 @@ envForMe( EnvThreadInfo* ti, const char* caller )
|
|||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
# define setGlobalState(s)
|
||||
#endif
|
||||
|
||||
JNIEnv*
|
||||
waitEnvFromGlobals() /* hanging */
|
||||
{
|
||||
JNIEnv* result = NULL;
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
pthread_mutex_lock( &g_globalStateLock );
|
||||
JNIGlobalState* state = g_globalState;
|
||||
if ( !!state ) {
|
||||
result = prvEnvForMe( &state->ti );
|
||||
}
|
||||
if ( !result ) {
|
||||
pthread_mutex_unlock( &g_globalStateLock );
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
releaseEnvFromGlobals( JNIEnv* env )
|
||||
{
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
XP_ASSERT( !!env );
|
||||
JNIGlobalState* state = g_globalState;
|
||||
XP_ASSERT( !!state );
|
||||
XP_ASSERT( env == prvEnvForMe( &state->ti ) );
|
||||
pthread_mutex_unlock( &g_globalStateLock );
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
tilesArrayToTileSet( JNIEnv* env, jintArray jtiles, TrayTileSet* tset )
|
||||
{
|
||||
|
@ -357,10 +376,11 @@ Java_org_eehouse_android_xw4_jni_XwJNI_initGlobals
|
|||
JNIGlobalState* globalState = (JNIGlobalState*)XP_CALLOC( mpool,
|
||||
sizeof(*globalState) );
|
||||
map_init( MPPARM(mpool) &globalState->ti, env );
|
||||
globalState->jniutil = makeJNIUtil( MPPARM(mpool) env, &globalState->ti, jniu );
|
||||
globalState->jniutil = makeJNIUtil( MPPARM(mpool) env, TI_IF(&globalState->ti) jniu );
|
||||
globalState->vtMgr = make_vtablemgr( MPPARM_NOCOMMA(mpool) );
|
||||
globalState->dutil = makeDUtil( MPPARM(mpool) env, jdutil,
|
||||
globalState->vtMgr, globalState->jniutil, NULL );
|
||||
globalState->dutil = makeDUtil( MPPARM(mpool) env, TI_IF(&globalState->ti)
|
||||
jdutil, globalState->vtMgr,
|
||||
globalState->jniutil, NULL );
|
||||
globalState->dictMgr = dmgr_make( MPPARM_NOCOMMA( mpool ) );
|
||||
globalState->smsProto = smsproto_init( MPPARM( mpool ) env, globalState->dutil );
|
||||
MPASSIGN( globalState->mpool, mpool );
|
||||
|
@ -380,7 +400,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_cleanGlobals
|
|||
#ifdef MEM_DEBUG
|
||||
MemPoolCtx* mpool = GETMPOOL( globalState );
|
||||
#endif
|
||||
XP_ASSERT( ENVFORME(&globalState->ti) == env );
|
||||
ASSERT_ENV( &globalState->ti, env );
|
||||
smsproto_free( globalState->smsProto );
|
||||
vtmgr_destroy( MPPARM(mpool) globalState->vtMgr );
|
||||
dmgr_destroy( globalState->dictMgr, env );
|
||||
|
@ -790,7 +810,8 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1getInfo
|
|||
MemPoolCtx* mpool = GETMPOOL( globalState );
|
||||
#endif
|
||||
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, globalState->dictMgr,
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(mpool) env, TI_IF(&globalState->ti)
|
||||
globalState->dictMgr,
|
||||
globalState->jniutil, jname, jDictBytes, jpath,
|
||||
NULL, check );
|
||||
if ( NULL != dict ) {
|
||||
|
@ -1001,8 +1022,10 @@ JNIEXPORT void JNICALL
|
|||
Java_org_eehouse_android_xw4_jni_XwJNI_envDone
|
||||
( JNIEnv* env, jclass C, jlong jniGlobalPtr )
|
||||
{
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
JNIGlobalState* globalJNI = (JNIGlobalState*)jniGlobalPtr;
|
||||
MAP_REMOVE( &globalJNI->ti, env );
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
|
@ -1015,15 +1038,19 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
|||
XWJNI_START_GLOBALS();
|
||||
CurGameInfo* gi = makeGI( MPPARM(mpool) env, j_gi );
|
||||
globals->gi = gi;
|
||||
globals->util = makeUtil( MPPARM(mpool) env, j_util, gi,
|
||||
globals );
|
||||
globals->util = makeUtil( MPPARM(mpool) env,
|
||||
TI_IF(&state->globalJNI->ti)
|
||||
j_util, gi, globals );
|
||||
globals->jniutil = state->globalJNI->jniutil;
|
||||
DrawCtx* dctx = NULL;
|
||||
if ( !!j_draw ) {
|
||||
dctx = makeDraw( MPPARM(mpool) env, j_draw );
|
||||
dctx = makeDraw( MPPARM(mpool) env,
|
||||
TI_IF(&state->globalJNI->ti) j_draw );
|
||||
}
|
||||
globals->dctx = dctx;
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) env, j_procs );
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) env,
|
||||
TI_IF(&state->globalJNI->ti)
|
||||
j_procs );
|
||||
CommonPrefs cp = {0};
|
||||
loadCommonPrefs( env, &cp, j_cp );
|
||||
|
||||
|
@ -1033,7 +1060,9 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
|||
DictionaryCtxt* dict;
|
||||
PlayerDicts dicts;
|
||||
|
||||
makeDicts( MPPARM(state->globalJNI->mpool) env, state->globalJNI->dictMgr,
|
||||
makeDicts( MPPARM(state->globalJNI->mpool) env,
|
||||
TI_IF(&state->globalJNI->ti)
|
||||
state->globalJNI->dictMgr,
|
||||
globals->jniutil, &dict, &dicts, j_names, j_dicts,
|
||||
j_paths, j_lang );
|
||||
#ifdef STUBBED_DICT
|
||||
|
@ -1085,15 +1114,23 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
|
|||
XWJNI_START_GLOBALS();
|
||||
|
||||
globals->gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*globals->gi) );
|
||||
globals->util = makeUtil( MPPARM(mpool) env, jutil, globals->gi, globals);
|
||||
globals->util = makeUtil( MPPARM(mpool) env,
|
||||
TI_IF(&state->globalJNI->ti)
|
||||
jutil, globals->gi, globals);
|
||||
globals->jniutil = state->globalJNI->jniutil;
|
||||
makeDicts( MPPARM(state->globalJNI->mpool) env, state->globalJNI->dictMgr,
|
||||
makeDicts( MPPARM(state->globalJNI->mpool) env,
|
||||
TI_IF(&state->globalJNI->ti)
|
||||
state->globalJNI->dictMgr,
|
||||
globals->jniutil, &dict, &dicts, jdictNames, jdicts, jpaths,
|
||||
jlang );
|
||||
if ( !!jdraw ) {
|
||||
globals->dctx = makeDraw( MPPARM(mpool) env, jdraw );
|
||||
globals->dctx = makeDraw( MPPARM(mpool) env,
|
||||
TI_IF(&state->globalJNI->ti)
|
||||
jdraw );
|
||||
}
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) env, jprocs );
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) env,
|
||||
TI_IF(&state->globalJNI->ti)
|
||||
jprocs );
|
||||
|
||||
XWStreamCtxt* stream = streamFromJStream( MPPARM(mpool) env,
|
||||
globals->vtMgr, jstream );
|
||||
|
@ -1167,7 +1204,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setDraw
|
|||
{
|
||||
XWJNI_START_GLOBALS();
|
||||
|
||||
DrawCtx* newDraw = makeDraw( MPPARM(mpool) env, jdraw );
|
||||
DrawCtx* newDraw = makeDraw( MPPARM(mpool) env, TI_IF(&state->globalJNI->ti) jdraw );
|
||||
board_setDraw( state->game.board, env, newDraw );
|
||||
|
||||
destroyDraw( &globals->dctx, env );
|
||||
|
@ -1202,7 +1239,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1drawSnapshot
|
|||
jint height )
|
||||
{
|
||||
XWJNI_START();
|
||||
DrawCtx* newDraw = makeDraw( MPPARM(mpool) env, jdraw );
|
||||
DrawCtx* newDraw = makeDraw( MPPARM(mpool) env, TI_IF(&state->globalJNI->ti) jdraw );
|
||||
board_drawSnapshot( state->game.board, env, newDraw, width, height );
|
||||
destroyDraw( &newDraw, env );
|
||||
XWJNI_END();
|
||||
|
@ -2102,7 +2139,8 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1changeDict
|
|||
jbyteArray jDictBytes, jstring jpath )
|
||||
{
|
||||
XWJNI_START_GLOBALS();
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(state->globalJNI->mpool) env,
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(state->globalJNI->mpool) env,
|
||||
TI_IF(&globalState->ti)
|
||||
state->globalJNI->dictMgr,
|
||||
globals->jniutil, jname, jDictBytes,
|
||||
jpath, NULL, false );
|
||||
|
@ -2297,8 +2335,11 @@ JNIEXPORT jboolean JNICALL
|
|||
Java_org_eehouse_android_xw4_jni_XwJNI_haveEnv
|
||||
( JNIEnv* env, jclass C, jlong jniGlobalPtr )
|
||||
{
|
||||
jboolean result = XP_TRUE;
|
||||
#ifdef MAP_THREAD_TO_ENV
|
||||
JNIGlobalState* globalState = (JNIGlobalState*)jniGlobalPtr;
|
||||
jboolean result = NULL != prvEnvForMe(&globalState->ti);
|
||||
result = NULL != prvEnvForMe(&globalState->ti);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2382,6 +2423,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1iter_1init
|
|||
MAP_THREAD( &globalState->ti, env );
|
||||
|
||||
DictionaryCtxt* dict = makeDict( MPPARM(globalState->mpool) env,
|
||||
TI_IF(&globalState->ti)
|
||||
globalState->dictMgr, globalState->jniutil,
|
||||
jname, jDictBytes, jpath, NULL, false );
|
||||
if ( !!dict ) {
|
||||
|
|
Loading…
Add table
Reference in a new issue