mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-04 20:46:28 +01:00
add debug-only checking for thread safety
Lots of threads call the smsproto code now so the existing check was failing. Replace it with one that ensures that only one thread at a time is running the code. Debug-builds only.
This commit is contained in:
parent
2b87d60cba
commit
1e397d07f4
1 changed files with 39 additions and 26 deletions
|
@ -77,10 +77,39 @@ struct SMSProto {
|
|||
|
||||
int nFromPhones;
|
||||
FromPhoneRec* fromPhoneRecs;
|
||||
|
||||
#ifdef DEBUG
|
||||
pthread_t starter;
|
||||
int nestCount;
|
||||
#endif
|
||||
MPSLOT;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
# define CHECK_START( state ) { \
|
||||
SMSProto* _state = state; \
|
||||
pthread_t _self = pthread_self(); \
|
||||
if ( _state->nestCount == 0 ) { \
|
||||
XP_ASSERT( _state->starter == 0 ); \
|
||||
_state->starter = _self; \
|
||||
} else { \
|
||||
XP_ASSERT( _state->starter == _self ); \
|
||||
} \
|
||||
++_state->nestCount; \
|
||||
XP_LOGF( "%s(): check: %d", __func__, _state->nestCount ); \
|
||||
|
||||
# define CHECK_END() \
|
||||
if ( --_state->nestCount == 0 ) { \
|
||||
_state->starter = 0; \
|
||||
} \
|
||||
XP_LOGF( "%s(): check: %d", __func__, _state->nestCount ); \
|
||||
} \
|
||||
|
||||
|
||||
#else
|
||||
# define CHECK_START(s)
|
||||
# define CHECK_END()
|
||||
#endif
|
||||
|
||||
#define KEY_PARTIALS PERSIST_KEY("partials")
|
||||
#define KEY_NEXTID PERSIST_KEY("nextID")
|
||||
|
||||
|
@ -105,18 +134,12 @@ static void freeMsgIDRec( SMSProto* state, MsgIDRec* rec, int fromPhoneIndex,
|
|||
static void freeForPhone( SMSProto* state, const XP_UCHAR* phone );
|
||||
static void freeMsg( SMSProto* state, MsgRec** msg );
|
||||
static void freeRec( SMSProto* state, ToPhoneRec* rec );
|
||||
#ifdef DEBUG
|
||||
static void checkThread( SMSProto* state );
|
||||
#else
|
||||
# define checkThread(p)
|
||||
#endif
|
||||
|
||||
SMSProto*
|
||||
smsproto_init( MPFORMAL XW_DUtilCtxt* dutil )
|
||||
{
|
||||
SMSProto* state = (SMSProto*)XP_CALLOC( mpool, sizeof(*state) );
|
||||
state->dutil = dutil;
|
||||
// checkThread( state ); <-- Android's calling this on background thread now
|
||||
MPASSIGN( state->mpool, mpool );
|
||||
|
||||
XP_U16 siz = sizeof(state->nNextID);
|
||||
|
@ -132,7 +155,6 @@ void
|
|||
smsproto_free( SMSProto* state )
|
||||
{
|
||||
if ( NULL != state ) {
|
||||
// checkThread( state ); <-- risky (see above)
|
||||
XP_ASSERT( state->creator == 0 || state->creator == pthread_self() );
|
||||
|
||||
for ( XP_U16 ii = 0; ii < state->nToPhones; ++ii ) {
|
||||
|
@ -213,6 +235,7 @@ smsproto_prepOutbound( SMSProto* state, SMS_CMD cmd, XP_U32 gameID,
|
|||
{
|
||||
XP_USE( toPort );
|
||||
SMSMsgArray* result = NULL;
|
||||
CHECK_START( state );
|
||||
|
||||
#ifdef DEBUG
|
||||
XP_UCHAR* checksum = dutil_md5sum( state->dutil, buf, buflen );
|
||||
|
@ -221,7 +244,6 @@ smsproto_prepOutbound( SMSProto* state, SMS_CMD cmd, XP_U32 gameID,
|
|||
XP_FREEP( state->mpool, &checksum );
|
||||
#endif
|
||||
|
||||
checkThread( state );
|
||||
ToPhoneRec* rec = getForPhone( state, toPhone, cmd != NONE );
|
||||
|
||||
/* First, add the new message (if present) to the array */
|
||||
|
@ -252,6 +274,7 @@ smsproto_prepOutbound( SMSProto* state, SMS_CMD cmd, XP_U32 gameID,
|
|||
|
||||
XP_LOGF( "%s() => %p (len=%d, *waitSecs=%d)", __func__, result,
|
||||
!!result ? result->nMsgs : 0, *waitSecsP );
|
||||
CHECK_END();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -292,12 +315,12 @@ smsproto_prepInbound( SMSProto* state, const XP_UCHAR* fromPhone,
|
|||
XP_U16 wantPort, const XP_U8* data, XP_U16 len )
|
||||
{
|
||||
XP_LOGF( "%s(): len=%d, fromPhone=%s", __func__, len, fromPhone );
|
||||
checkThread( state );
|
||||
SMSMsgArray* result = NULL;
|
||||
CHECK_START( state );
|
||||
|
||||
XWStreamCtxt* stream = mkStream( state );
|
||||
stream_putBytes( stream, data, len );
|
||||
|
||||
SMSMsgArray* result = NULL;
|
||||
XP_U8 proto;
|
||||
if ( stream_gotU8( stream, &proto ) ) {
|
||||
switch ( proto ) {
|
||||
|
@ -361,13 +384,14 @@ smsproto_prepInbound( SMSProto* state, const XP_UCHAR* fromPhone,
|
|||
stream_destroy( stream );
|
||||
|
||||
XP_LOGF( "%s() => %p (len=%d)", __func__, result, (!!result) ? result->nMsgs : 0 );
|
||||
CHECK_END();
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
smsproto_freeMsgArray( SMSProto* state, SMSMsgArray* arr )
|
||||
{
|
||||
checkThread( state );
|
||||
CHECK_START( state );
|
||||
|
||||
for ( int ii = 0; ii < arr->nMsgs; ++ii ) {
|
||||
XP_U8** ptr = arr->format == FORMAT_LOC
|
||||
|
@ -389,6 +413,7 @@ smsproto_freeMsgArray( SMSProto* state, SMSMsgArray* arr )
|
|||
}
|
||||
XP_FREEP( state->mpool, ptr );
|
||||
XP_FREEP( state->mpool, &arr );
|
||||
CHECK_END();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -620,7 +645,7 @@ freeMsgIDRec( SMSProto* state, MsgIDRec* rec, int fromPhoneIndex, int msgIDIndex
|
|||
static void
|
||||
savePartials( SMSProto* state )
|
||||
{
|
||||
checkThread( state );
|
||||
CHECK_START( state );
|
||||
|
||||
XWStreamCtxt* stream = mkStream( state );
|
||||
stream_putU8( stream, PARTIALS_FORMAT );
|
||||
|
@ -655,6 +680,7 @@ savePartials( SMSProto* state )
|
|||
stream_destroy( stream );
|
||||
|
||||
LOG_RETURN_VOID();
|
||||
CHECK_END();
|
||||
} /* savePartials */
|
||||
|
||||
static void
|
||||
|
@ -840,19 +866,6 @@ mkStream( SMSProto* state )
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
checkThread( SMSProto* state )
|
||||
{
|
||||
pthread_t curThread = pthread_self();
|
||||
if ( 0 == state->creator ) {
|
||||
state->creator = curThread;
|
||||
} else {
|
||||
/* If this is firing will need to use a mutex to make SMSProto access
|
||||
thread-safe */
|
||||
XP_ASSERT( state->creator == curThread );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
smsproto_runTests( MPFORMAL XW_DUtilCtxt* dutil )
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue