diff --git a/xwords4/common/device.c b/xwords4/common/device.c index 7ed8316eb..de753bed1 100644 --- a/xwords4/common/device.c +++ b/xwords4/common/device.c @@ -575,7 +575,7 @@ static void setAckSendTimerLocked( XW_DUtilCtxt* dutil, XWEnv xwe, DevCtxt* dc ) { if ( 0 == dc->ackTimer.key ) { - XP_U32 inWhenMS = 10 * 1000; + XP_U32 inWhenMS = 7500; dc->ackTimer.key = tmr_set( dutil, xwe, inWhenMS, onAckSendTimer, dutil ); XP_ASSERT( 0 != dc->ackTimer.key ); diff --git a/xwords4/common/dictmgr.c b/xwords4/common/dictmgr.c index 3b184e65d..bfc0b7d42 100644 --- a/xwords4/common/dictmgr.c +++ b/xwords4/common/dictmgr.c @@ -22,6 +22,7 @@ #include "dictnry.h" #include "strutils.h" #include "dictmgr.h" +#include "xwmutex.h" #ifdef CPLUS extern "C" { @@ -44,7 +45,7 @@ typedef struct _DictPair { struct DictMgrCtxt { DictPair pairs[DMGR_MAX_DICTS]; - pthread_mutex_t mutex; + MutexState mutex; MPSLOT }; @@ -63,7 +64,7 @@ DictMgrCtxt* dmgr_make( MPFORMAL_NOCOMMA ) { DictMgrCtxt* dmgr = XP_CALLOC( mpool, sizeof(*dmgr) ); - pthread_mutex_init( &dmgr->mutex, NULL ); + mtx_init( &dmgr->mutex, XP_FALSE ); MPASSIGN( dmgr->mpool, mpool ); return dmgr; } @@ -77,7 +78,7 @@ dmgr_destroy( DictMgrCtxt* dmgr, XWEnv xwe ) dict_unref( pair->dict, xwe ); XP_FREEP( dmgr->mpool, &pair->key ); } - pthread_mutex_destroy( &dmgr->mutex ); + mtx_destroy( &dmgr->mutex ); XP_FREE( dmgr->mpool, dmgr ); } @@ -86,7 +87,7 @@ dmgr_get( DictMgrCtxt* dmgr, XWEnv xwe, const XP_UCHAR* key ) { const DictionaryCtxt* result = NULL; - pthread_mutex_lock( &dmgr->mutex ); + WITH_MUTEX( &dmgr->mutex ); XP_S16 index = findFor( dmgr, key ); if ( 0 <= index ) { @@ -96,14 +97,14 @@ dmgr_get( DictMgrCtxt* dmgr, XWEnv xwe, const XP_UCHAR* key ) XP_LOGFF( "(key=%s)=>%p", key, result ); printInOrder( dmgr ); - pthread_mutex_unlock( &dmgr->mutex ); + END_WITH_MUTEX(); return result; } void dmgr_put( DictMgrCtxt* dmgr, XWEnv xwe, const XP_UCHAR* key, const DictionaryCtxt* dict ) { - pthread_mutex_lock( &dmgr->mutex ); + WITH_MUTEX( &dmgr->mutex ); XP_S16 loc = findFor( dmgr, key ); if ( NOT_FOUND == loc ) { /* reuse the last one */ @@ -118,7 +119,7 @@ dmgr_put( DictMgrCtxt* dmgr, XWEnv xwe, const XP_UCHAR* key, const DictionaryCtx XP_LOGFF( "(key=%s, dict=%p)", key, dict ); printInOrder( dmgr ); - pthread_mutex_unlock( &dmgr->mutex ); + END_WITH_MUTEX(); } static XP_S16 diff --git a/xwords4/common/dictnry.c b/xwords4/common/dictnry.c index 8720dce91..be27a9ccd 100644 --- a/xwords4/common/dictnry.c +++ b/xwords4/common/dictnry.c @@ -31,6 +31,7 @@ #include "dictiter.h" #include "game.h" #include "dbgutil.h" +#include "xwmutex.h" #ifdef CPLUS extern "C" { @@ -52,13 +53,13 @@ p_dict_ref( const DictionaryCtxt* dict, XWEnv XP_UNUSED(xwe) { if ( !!dict ) { DictionaryCtxt* _dict = (DictionaryCtxt*)dict; - pthread_mutex_lock( &_dict->mutex ); + WITH_MUTEX( &_dict->mutex ); ++_dict->refCount; #ifdef DEBUG_REF XP_LOGFF( "(dict=%p): refCount now %d (from line %d of %s() in %s)", dict, dict->refCount, line, func, file ); #endif - pthread_mutex_unlock( &_dict->mutex ); + END_WITH_MUTEX(); } return dict; } @@ -72,7 +73,7 @@ p_dict_unref( const DictionaryCtxt* dict, XWEnv xwe { if ( !!dict ) { DictionaryCtxt* _dict = (DictionaryCtxt*)dict; - pthread_mutex_lock( &_dict->mutex ); + WITH_MUTEX( &_dict->mutex ); XP_ASSERT( 0 != _dict->refCount ); --_dict->refCount; XP_ASSERT( 0 <= _dict->refCount ); @@ -80,11 +81,11 @@ p_dict_unref( const DictionaryCtxt* dict, XWEnv xwe XP_LOGFF( "(dict=%p): refCount now %d (from line %d of %s() in %s)", dict, dict->refCount, line, func, file ); #endif - pthread_mutex_unlock( &_dict->mutex ); + END_WITH_MUTEX(); if ( 0 == _dict->refCount ) { /* There's a race here. If another thread locks the mutex we'll still destroy the dict (and the locked mutex!!!) PENDING */ - pthread_mutex_destroy( &_dict->mutex ); + mtx_destroy( &_dict->mutex ); (*dict->destructor)( _dict, xwe ); } } @@ -1208,7 +1209,7 @@ dict_super_init( MPFORMAL DictionaryCtxt* dict ) dict->func_dict_edge_with_tile = dict_super_edge_with_tile; dict->func_dict_getShortName = dict_getName; - pthread_mutex_init( &dict->mutex, NULL ); + mtx_init( &dict->mutex, XP_FALSE ); } /* dict_super_init */ void diff --git a/xwords4/common/dictnry.h b/xwords4/common/dictnry.h index 80a4ea2f8..086546855 100644 --- a/xwords4/common/dictnry.h +++ b/xwords4/common/dictnry.h @@ -32,6 +32,7 @@ #include "dawg.h" #include "model.h" #include "mempool.h" +#include "xwmutex.h" #ifdef CPLUS extern "C" { @@ -74,7 +75,7 @@ struct DictionaryCtxt { array_edge* from, Tile tile ); const XP_UCHAR* (*func_dict_getShortName)( const DictionaryCtxt* dict ); - pthread_mutex_t mutex; + MutexState mutex; array_edge* topEdge; array_edge* base; /* the physical beginning of the dictionary; not diff --git a/xwords4/common/dutil.c b/xwords4/common/dutil.c index 0ba7ede9b..cd255fb67 100644 --- a/xwords4/common/dutil.c +++ b/xwords4/common/dutil.c @@ -59,7 +59,7 @@ void dutil_super_init( MPFORMAL XW_DUtilCtxt* dutil ) { #ifdef XWFEATURE_KNOWNPLAYERS - pthread_mutex_init( &dutil->kpMutex, NULL ); + mtx_init( &dutil->kpMutex, XP_FALSE ); #endif MPASSIGN( dutil->mpool, mpool ); diff --git a/xwords4/common/dutil.h b/xwords4/common/dutil.h index a9dad67ac..87471b9d3 100644 --- a/xwords4/common/dutil.h +++ b/xwords4/common/dutil.h @@ -28,6 +28,7 @@ #include "vtabmgr.h" #include "commstyp.h" #include "nlityp.h" +#include "xwmutex.h" #include "cJSON.h" typedef enum { UNPAUSED, @@ -120,7 +121,7 @@ struct XW_DUtilCtxt { void* timersState; /* owned by timers.c */ #ifdef XWFEATURE_KNOWNPLAYERS /* owned by knownplyr.c */ void* kpCtxt; - pthread_mutex_t kpMutex; + MutexState kpMutex; #endif VTableMgr* vtMgr; #ifdef DEBUG diff --git a/xwords4/common/knownplyr.c b/xwords4/common/knownplyr.c index 060c88955..f46d55069 100644 --- a/xwords4/common/knownplyr.c +++ b/xwords4/common/knownplyr.c @@ -61,11 +61,9 @@ loadFromStream( XW_DUtilCtxt* dutil, KPState* state, XWStreamCtxt* stream ) } static KPState* -loadState( XW_DUtilCtxt* dutil, XWEnv xwe ) +loadStateLocked( XW_DUtilCtxt* dutil, XWEnv xwe ) { // LOG_FUNC(); - pthread_mutex_lock( &dutil->kpMutex ); - KPState* state = (KPState*)dutil->kpCtxt; if ( NULL == state ) { dutil->kpCtxt = state = XP_CALLOC( dutil->mpool, sizeof(*state) ); @@ -116,13 +114,11 @@ saveState( XW_DUtilCtxt* dutil, XWEnv xwe, KPState* state ) } static void -releaseState( XW_DUtilCtxt* dutil, XWEnv xwe, KPState* state ) +releaseStateLocked( XW_DUtilCtxt* dutil, XWEnv xwe, KPState* state ) { XP_ASSERT( state->inUse ); saveState( dutil, xwe, state ); state->inUse = XP_FALSE; - - pthread_mutex_unlock( &dutil->kpMutex ); } static void @@ -249,9 +245,11 @@ kplr_addAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const CommsAddrRec* addr, XP_ASSERT( !!name ); XP_Bool canUse = addr_hasType( addr, COMMS_CONN_MQTT ); if ( canUse ) { - KPState* state = loadState( dutil, xwe ); + WITH_MUTEX( &dutil->kpMutex ); + KPState* state = loadStateLocked( dutil, xwe ); addPlayer( dutil, state, name, addr, modTime ); - releaseState( dutil, xwe, state ); + releaseStateLocked( dutil, xwe, state ); + END_WITH_MUTEX(); } XP_LOGFFV( "=>%s", boolToStr(canUse) ); @@ -261,9 +259,12 @@ kplr_addAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const CommsAddrRec* addr, XP_Bool kplr_havePlayers( XW_DUtilCtxt* dutil, XWEnv xwe ) { - KPState* state = loadState( dutil, xwe ); - XP_Bool result = 0 < dll_length( &state->players->links ); - releaseState( dutil, xwe, state ); + XP_Bool result; + WITH_MUTEX( &dutil->kpMutex ); + KPState* state = loadStateLocked( dutil, xwe ); + result = 0 < dll_length( &state->players->links ); + releaseStateLocked( dutil, xwe, state ); + END_WITH_MUTEX(); LOG_RETURNF( "%s", boolToStr(result) ); return result; } @@ -303,7 +304,8 @@ void kplr_getNames( XW_DUtilCtxt* dutil, XWEnv xwe, XP_Bool byDate, const XP_UCHAR** players, XP_U16* nFound ) { - KPState* state = loadState( dutil, xwe ); + WITH_MUTEX( &dutil->kpMutex ); + KPState* state = loadStateLocked( dutil, xwe ); if ( byDate ) { state->players = (KnownPlayer*)dll_sort( &state->players->links, compByDate ); @@ -313,7 +315,8 @@ kplr_getNames( XW_DUtilCtxt* dutil, XWEnv xwe, XP_Bool byDate, state->players = (KnownPlayer*)dll_sort( &state->players->links, compByName ); } - releaseState( dutil, xwe, state ); + releaseStateLocked( dutil, xwe, state ); + END_WITH_MUTEX(); } typedef struct _FindState { @@ -350,8 +353,9 @@ XP_Bool kplr_getAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name, CommsAddrRec* addr, XP_U32* lastMod ) { - KPState* state = loadState( dutil, xwe ); XP_Bool found = XP_FALSE; + WITH_MUTEX( &dutil->kpMutex ); + KPState* state = loadStateLocked( dutil, xwe ); KnownPlayer* kp = findByName( state, name ); found = NULL != kp; if ( found ) { @@ -360,7 +364,8 @@ kplr_getAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name, *lastMod = kp->newestMod; } } - releaseState( dutil, xwe, state ); + releaseStateLocked( dutil, xwe, state ); + END_WITH_MUTEX(); LOG_RETURNF( "%s", boolToStr(found) ); return found; } @@ -401,13 +406,15 @@ kplr_nameForAddress( XW_DUtilCtxt* dutil, XWEnv xwe, const CommsAddrRec* addr ) { MDevState ms = {.addr = addr}; - KPState* state = loadState( dutil, xwe ); + WITH_MUTEX( &dutil->kpMutex ); + KPState* state = loadStateLocked( dutil, xwe ); #ifdef DEBUG DLHead* head = #endif dll_map( &state->players->links, addrProc, NULL, &ms ); XP_ASSERT( head == &state->players->links ); - releaseState( dutil, xwe, state ); + releaseStateLocked( dutil, xwe, state ); + END_WITH_MUTEX(); XP_LOGFF( "=> %s", ms.name ); return ms.name; @@ -425,7 +432,8 @@ kplr_renamePlayer( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* oldName, const XP_UCHAR* newName ) { KP_Rslt result; - KPState* state = loadState( dutil, xwe ); + WITH_MUTEX( &dutil->kpMutex ); + KPState* state = loadStateLocked( dutil, xwe ); KnownPlayer* kp = findByName( state, oldName ); if ( !kp ) { @@ -439,7 +447,8 @@ kplr_renamePlayer( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* oldName, result = KP_OK; } - releaseState( dutil, xwe, state ); + releaseStateLocked( dutil, xwe, state ); + END_WITH_MUTEX(); return result; } @@ -474,12 +483,14 @@ KP_Rslt kplr_deletePlayer( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name ) { KP_Rslt result = KP_OK; - KPState* state = loadState( dutil, xwe ); + WITH_MUTEX( &dutil->kpMutex ); + KPState* state = loadStateLocked( dutil, xwe ); DelState ds = { .name = name, .state = state, .dutil = dutil,}; state->players = (KnownPlayer*) dll_map( &state->players->links, delMapProc, delFreeProc, &ds ); - releaseState( dutil, xwe, state ); + releaseStateLocked( dutil, xwe, state ); + END_WITH_MUTEX(); return result; } diff --git a/xwords4/common/smsproto.c b/xwords4/common/smsproto.c index dcf18ae2b..3fc5350a5 100644 --- a/xwords4/common/smsproto.c +++ b/xwords4/common/smsproto.c @@ -24,6 +24,7 @@ #include "smsproto.h" #include "comtypes.h" #include "strutils.h" +#include "xwmutex.h" #define MAX_WAIT 3 // # define MAX_MSG_LEN 50 /* for testing */ @@ -71,7 +72,7 @@ typedef struct _FromPhoneRec { struct SMSProto { XW_DUtilCtxt* dutil; pthread_t creator; - pthread_mutex_t mutex; + MutexState mutex; XP_U16 nNextID; int lastStoredSize; XP_U16 nToPhones; @@ -120,7 +121,7 @@ SMSProto* smsproto_init( MPFORMAL XWEnv xwe, XW_DUtilCtxt* dutil ) { SMSProto* state = (SMSProto*)XP_CALLOC( mpool, sizeof(*state) ); - pthread_mutex_init( &state->mutex, NULL ); + mtx_init( &state->mutex, XP_FALSE ); state->dutil = dutil; MPASSIGN( state->mpool, mpool ); @@ -156,7 +157,7 @@ smsproto_free( SMSProto* state ) } XP_ASSERT( !state->fromPhoneRecs ); /* above nulls this once empty */ - pthread_mutex_destroy( &state->mutex ); + mtx_destroy( &state->mutex ); XP_FREEP( state->mpool, &state ); } @@ -220,7 +221,7 @@ smsproto_prepOutbound( SMSProto* state, XWEnv xwe, SMS_CMD cmd, XP_U32 gameID, { XP_USE( toPort ); SMSMsgArray* result = NULL; - pthread_mutex_lock( &state->mutex ); + WITH_MUTEX( &state->mutex ); #if defined DEBUG Md5SumBuf sb; @@ -260,7 +261,7 @@ smsproto_prepOutbound( SMSProto* state, XWEnv xwe, SMS_CMD cmd, XP_U32 gameID, XP_LOGF( "%s() => %p (count=%d, *waitSecs=%d)", __func__, result, !!result ? result->nMsgs : 0, *waitSecsP ); - pthread_mutex_unlock( &state->mutex ); + END_WITH_MUTEX(); logResult( state, xwe, result, __func__ ); return result; } /* smsproto_prepOutbound */ @@ -310,7 +311,7 @@ smsproto_prepInbound( SMSProto* state, XWEnv xwe, const XP_UCHAR* fromPhone, #endif SMSMsgArray* result = NULL; - pthread_mutex_lock( &state->mutex ); + WITH_MUTEX( &state->mutex ); XWStreamCtxt* stream = mkStream( state ); stream_putBytes( stream, data, len ); @@ -380,14 +381,14 @@ smsproto_prepInbound( SMSProto* state, XWEnv xwe, const XP_UCHAR* fromPhone, XP_LOGFF( "=> %p (len=%d)", result, (!!result) ? result->nMsgs : 0 ); logResult( state, xwe, result, __func__ ); - pthread_mutex_unlock( &state->mutex ); + END_WITH_MUTEX(); return result; } void smsproto_freeMsgArray( SMSProto* state, SMSMsgArray* arr ) { - pthread_mutex_lock( &state->mutex ); + WITH_MUTEX( &state->mutex ); for ( int ii = 0; ii < arr->nMsgs; ++ii ) { XP_U8** ptr = arr->format == FORMAT_LOC @@ -409,7 +410,7 @@ smsproto_freeMsgArray( SMSProto* state, SMSMsgArray* arr ) } XP_FREEP( state->mpool, ptr ); XP_FREEP( state->mpool, &arr ); - pthread_mutex_unlock( &state->mutex ); + END_WITH_MUTEX(); } #if defined DEBUG diff --git a/xwords4/linux/scripts/netGamesTest.py b/xwords4/linux/scripts/netGamesTest.py index c087319e1..0b3b08710 100755 --- a/xwords4/linux/scripts/netGamesTest.py +++ b/xwords4/linux/scripts/netGamesTest.py @@ -615,6 +615,7 @@ class Device(): self._stats = stats def _checkScript(self): + assert os.path.exists(self.args.APP_NEW) if not os.path.exists(self.script): scriptArgs = ['exec'] # without exec means terminate() won't work if self.args.VALGRIND: @@ -915,7 +916,7 @@ def mkParser(): parser.add_argument('--timer-seconds', dest='TIMER_SECS', default=10, type=int, help='Enable game timer with game this many seconds long') - parser.add_argument('--min-app-life', dest='MIN_APP_LIFE', default=5, type=int, + parser.add_argument('--min-app-life', dest='MIN_APP_LIFE', default=15, type=int, help='Minimum number of seconds app will run after each launch') parser.add_argument('--with-sms', dest = 'WITH_SMS', action = 'store_true')