mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-15 20:48:00 +01:00
add mutex utility
since I'm using them more now
This commit is contained in:
parent
041684a355
commit
72082cde0d
5 changed files with 151 additions and 101 deletions
|
@ -88,6 +88,7 @@ COMMON_SRC_FILES += \
|
|||
$(COMMON_PATH)/server.c \
|
||||
$(COMMON_PATH)/model.c \
|
||||
$(COMMON_PATH)/comms.c \
|
||||
$(COMMON_PATH)/xwmutex.c \
|
||||
$(COMMON_PATH)/memstream.c \
|
||||
$(COMMON_PATH)/movestak.c \
|
||||
$(COMMON_PATH)/dbgutil.c \
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "device.h"
|
||||
#include "nli.h"
|
||||
#include "dllist.h"
|
||||
#include "xwmutex.h"
|
||||
|
||||
#define HEARTBEAT_NONE 0
|
||||
|
||||
|
@ -185,58 +186,6 @@ struct CommsCtxt {
|
|||
MPSLOT
|
||||
};
|
||||
|
||||
static void
|
||||
mutex_init(CommsCtxt* comms)
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
int ret = pthread_mutexattr_init(&attr);
|
||||
XP_ASSERT(0 == ret);
|
||||
ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
XP_ASSERT(0 == ret);
|
||||
pthread_mutex_init( &comms->mutex, &attr );
|
||||
ret = pthread_mutexattr_destroy(&attr);
|
||||
XP_ASSERT(0 == ret);
|
||||
}
|
||||
|
||||
#define COMMS_MUTEX_LOCK_DEBUG(COMMS) { \
|
||||
CommsCtxt* _comms = COMMS; \
|
||||
time_t startTime = time(NULL); \
|
||||
pthread_mutex_lock(&_comms->mutex); \
|
||||
time_t gotItTime = time(NULL); \
|
||||
time_t _elapsed = gotItTime-startTime; \
|
||||
if ( 0 < _elapsed ) { \
|
||||
XP_LOGFF("took %lds to get mutex", _elapsed); \
|
||||
} \
|
||||
pthread_t _oldHolder = comms->lockHolder; \
|
||||
comms->lockHolder = pthread_self(); \
|
||||
XP_ASSERT(0 == _oldHolder || _oldHolder == comms->lockHolder); \
|
||||
|
||||
#define COMMS_MUTEX_UNLOCK_DEBUG() \
|
||||
time_t unlockTime = time(NULL); \
|
||||
_elapsed = unlockTime-gotItTime; \
|
||||
if ( 0 < _elapsed ) { \
|
||||
XP_LOGFF("held mutex for %lds", _elapsed); \
|
||||
} \
|
||||
comms->lockHolder = _oldHolder; \
|
||||
pthread_mutex_unlock(&_comms->mutex); \
|
||||
} \
|
||||
|
||||
#define COMMS_MUTEX_LOCK_RELEASE(COMMS) { \
|
||||
CommsCtxt* _comms = COMMS; \
|
||||
pthread_mutex_lock(&_comms->mutex); \
|
||||
|
||||
#define COMMS_MUTEX_UNLOCK_RELEASE() \
|
||||
pthread_mutex_unlock(&_comms->mutex); \
|
||||
} \
|
||||
|
||||
#ifdef DEBUG
|
||||
#define COMMS_MUTEX_LOCK COMMS_MUTEX_LOCK_DEBUG
|
||||
#define COMMS_MUTEX_UNLOCK COMMS_MUTEX_UNLOCK_DEBUG
|
||||
#else
|
||||
#define COMMS_MUTEX_LOCK COMMS_MUTEX_LOCK_RELEASE
|
||||
#define COMMS_MUTEX_UNLOCK COMMS_MUTEX_UNLOCK_RELEASE
|
||||
#endif
|
||||
|
||||
#define _FLAG_HARVEST_DONE 1 /* no longer used */
|
||||
#define FLAG_QUASHED 2
|
||||
|
||||
|
@ -468,7 +417,7 @@ comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer,
|
|||
XP_U16 forceChannel )
|
||||
{
|
||||
CommsCtxt* comms = (CommsCtxt*)XP_CALLOC( mpool, sizeof(*comms) );
|
||||
mutex_init(comms);
|
||||
initMutex( &comms->mutex, XP_TRUE );
|
||||
comms->util = util;
|
||||
comms->dutil = util_getDevUtilCtxt( util, xwe );
|
||||
#ifdef DEBUG
|
||||
|
@ -533,7 +482,7 @@ static void
|
|||
forEachElem( CommsCtxt* comms, EachMsgProc proc, void* closure )
|
||||
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
for ( AddressRecord* recs = comms->recs; !!recs; recs = recs->next ) {
|
||||
for ( MsgQueueElem** home = &recs->_msgQueueHead; !!*home; ) {
|
||||
MsgQueueElem* elem = *home;
|
||||
|
@ -556,7 +505,7 @@ forEachElem( CommsCtxt* comms, EachMsgProc proc, void* closure )
|
|||
}
|
||||
done:
|
||||
assertQueueOk( comms );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
}
|
||||
|
||||
static ForEachAct
|
||||
|
@ -627,7 +576,7 @@ set_reset_timer( CommsCtxt* comms, XWEnv xwe )
|
|||
void
|
||||
comms_destroy( CommsCtxt* comms, XWEnv xwe )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
/* did I call comms_stop()? */
|
||||
XP_ASSERT( ! addr_hasType( &comms->selfAddr, COMMS_CONN_RELAY )
|
||||
|| COMMS_RELAYSTATE_UNCONNECTED == comms->rr.relayState );
|
||||
|
@ -637,14 +586,14 @@ comms_destroy( CommsCtxt* comms, XWEnv xwe )
|
|||
|
||||
util_clearTimer( comms->util, xwe, TIMER_COMMS );
|
||||
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
XP_FREE( comms->mpool, comms );
|
||||
} /* comms_destroy */
|
||||
|
||||
void
|
||||
comms_setConnID( CommsCtxt* comms, XP_U32 connID, XP_U16 streamVersion )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
XP_ASSERT( CONN_ID_NONE != connID );
|
||||
XP_ASSERT( 0 == comms->connID || connID == comms->connID );
|
||||
comms->connID = connID;
|
||||
|
@ -653,7 +602,7 @@ comms_setConnID( CommsCtxt* comms, XP_U32 connID, XP_U16 streamVersion )
|
|||
comms->streamVersion = streamVersion;
|
||||
COMMS_LOGFF( "set connID (gameID) to %08X, streamVersion to 0x%X",
|
||||
connID, streamVersion );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
} /* comms_setConnID */
|
||||
|
||||
static void
|
||||
|
@ -1163,7 +1112,7 @@ elemToStream( MsgQueueElem* elem, void* closure )
|
|||
void
|
||||
comms_writeToStream( CommsCtxt* comms, XWStreamCtxt* stream, XP_U16 saveToken )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
XP_U16 nAddrRecs;
|
||||
AddressRecord* rec;
|
||||
|
||||
|
@ -1242,7 +1191,7 @@ comms_writeToStream( CommsCtxt* comms, XWStreamCtxt* stream, XP_U16 saveToken )
|
|||
}
|
||||
|
||||
comms->lastSaveToken = saveToken;
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
} /* comms_writeToStream */
|
||||
|
||||
static void
|
||||
|
@ -1256,7 +1205,7 @@ resetBackoff( CommsCtxt* comms )
|
|||
void
|
||||
comms_saveSucceeded( CommsCtxt* comms, XWEnv xwe, XP_U16 saveToken )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
COMMS_LOGFF( "(saveToken=%d)", saveToken );
|
||||
XP_ASSERT( !!comms );
|
||||
if ( saveToken == comms->lastSaveToken ) {
|
||||
|
@ -1270,7 +1219,7 @@ comms_saveSucceeded( CommsCtxt* comms, XWEnv xwe, XP_U16 saveToken )
|
|||
comms_ackAny( comms, xwe ); /* might not want this for all transports */
|
||||
#endif
|
||||
}
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1298,7 +1247,7 @@ void
|
|||
comms_addMQTTDevID( CommsCtxt* comms, XP_PlayerAddr channelNo,
|
||||
const MQTTDevID* devID )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
#ifdef NO_ADD_MQTT_TO_ALL /* set for (usually) BT testing on Android */
|
||||
COMMS_LOGFF("ifdef'd out");
|
||||
XP_USE( comms );
|
||||
|
@ -1333,7 +1282,7 @@ comms_addMQTTDevID( CommsCtxt* comms, XP_PlayerAddr channelNo,
|
|||
XP_ASSERT(0);
|
||||
}
|
||||
#endif
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1425,7 +1374,7 @@ XP_U16
|
|||
comms_countPendingPackets( RELCONST CommsCtxt* comms, XP_Bool* quashed )
|
||||
{
|
||||
NonAcks na = {0};
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
if ( !!quashed ) {
|
||||
*quashed = QUASHED(comms);
|
||||
}
|
||||
|
@ -1433,7 +1382,7 @@ comms_countPendingPackets( RELCONST CommsCtxt* comms, XP_Bool* quashed )
|
|||
forEachElem( (CommsCtxt*)comms, countNonAcks, &na );
|
||||
|
||||
// COMMS_LOGFF( "=> %d (queueLen = %d)", na.count, comms->queueLen );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
return na.count;
|
||||
}
|
||||
|
||||
|
@ -1504,10 +1453,10 @@ comms_getConTypes( const CommsCtxt* comms )
|
|||
void
|
||||
comms_dropHostAddr( CommsCtxt* comms, CommsConnType typ )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
addr_rmType( &comms->selfAddr, typ );
|
||||
ASSERT_ADDR_OK( &comms->selfAddr );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
|
@ -1784,7 +1733,7 @@ comms_invite( CommsCtxt* comms, XWEnv xwe, const NetLaunchInfo* nli,
|
|||
{
|
||||
COMMS_LOGFF("(sendNow=%s)", boolToStr(sendNow));
|
||||
LOGNLI(nli);
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
XP_PlayerAddr forceChannel = pickChannel(comms, nli, destAddr);
|
||||
XP_LOGFF( "forceChannel: %d", forceChannel );
|
||||
XP_ASSERT( 0 < forceChannel && (forceChannel & CHANNEL_MASK) == forceChannel );
|
||||
|
@ -1821,7 +1770,7 @@ comms_invite( CommsCtxt* comms, XWEnv xwe, const NetLaunchInfo* nli,
|
|||
} else {
|
||||
XP_LOGFF( "dropping invite; no open channel found" );
|
||||
}
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
|
@ -1850,12 +1799,12 @@ getInvitedProc( MsgQueueElem* elem, void* closure )
|
|||
void
|
||||
comms_getInvited( RELCONST CommsCtxt* comms, XP_U16* nInvites )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
GetInvitedData gid = {0};
|
||||
forEachElem( (CommsCtxt*)comms, getInvitedProc, &gid );
|
||||
*nInvites = gid.count;
|
||||
// LOG_RETURNF( "%d", *nInvites );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
}
|
||||
|
||||
typedef struct _GetNamesData {
|
||||
|
@ -1893,14 +1842,14 @@ void
|
|||
comms_inviteeNames( CommsCtxt* comms, XWEnv xwe,
|
||||
InviteeNames* names )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
GetNamesData gnd = {
|
||||
.comms = comms,
|
||||
.xwe = xwe,
|
||||
.names = names,
|
||||
};
|
||||
forEachElem( (CommsCtxt*)comms, getNamesProc, &gnd );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1910,7 +1859,7 @@ XP_S16
|
|||
comms_send( CommsCtxt* comms, XWEnv xwe, XWStreamCtxt* stream )
|
||||
{
|
||||
XP_S16 result = -1;
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
if ( 0 == stream_getSize(stream) ) {
|
||||
COMMS_LOGFF( "dropping 0-len message" );
|
||||
} else {
|
||||
|
@ -1937,7 +1886,7 @@ comms_send( CommsCtxt* comms, XWEnv xwe, XWStreamCtxt* stream )
|
|||
}
|
||||
}
|
||||
}
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
return result;
|
||||
} /* comms_send */
|
||||
|
||||
|
@ -1959,7 +1908,7 @@ static MsgQueueElem*
|
|||
addToQueue( CommsCtxt* comms, XWEnv xwe, MsgQueueElem* newElem, XP_Bool notify )
|
||||
{
|
||||
MsgQueueElem* asAdded = newElem;
|
||||
COMMS_MUTEX_LOCK( comms );
|
||||
WITH_MUTEX( &comms->mutex );
|
||||
newElem->smp.next = NULL;
|
||||
|
||||
MsgQueueElem** head;
|
||||
|
@ -1999,7 +1948,7 @@ addToQueue( CommsCtxt* comms, XWEnv xwe, MsgQueueElem* newElem, XP_Bool notify )
|
|||
}
|
||||
dropPacket:
|
||||
XP_ASSERT( comms->queueLen <= 128 ); /* reasonable limit in testing */
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
return asAdded;
|
||||
} /* addToQueue */
|
||||
|
||||
|
@ -2135,7 +2084,7 @@ removeProc( MsgQueueElem* elem, void* closure )
|
|||
static void
|
||||
removeFromQueue( CommsCtxt* comms, XWEnv xwe, XP_PlayerAddr channelNo, MsgID msgID )
|
||||
{
|
||||
COMMS_MUTEX_LOCK( comms );
|
||||
WITH_MUTEX( &comms->mutex );
|
||||
assertQueueOk( comms );
|
||||
CNO_FMT( cbuf, channelNo );
|
||||
COMMS_LOGFFV( "(channelNo=%d): remove msgs <= " XP_LD " for %s (queueLen: %d)",
|
||||
|
@ -2163,7 +2112,7 @@ removeFromQueue( CommsCtxt* comms, XWEnv xwe, XP_PlayerAddr channelNo, MsgID msg
|
|||
assertQueueOk( comms );
|
||||
printQueue( comms );
|
||||
#endif
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
} /* removeFromQueue */
|
||||
|
||||
static XP_U32
|
||||
|
@ -2444,7 +2393,7 @@ comms_resendAll( CommsCtxt* comms, XWEnv xwe, CommsConnType filter, XP_Bool forc
|
|||
static void
|
||||
ackAnyImpl( CommsCtxt* comms, XWEnv xwe, XP_Bool force )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
if ( CONN_ID_NONE == comms->connID ) {
|
||||
COMMS_LOGFF( "doing nothing because connID still unset" );
|
||||
} else {
|
||||
|
@ -2469,7 +2418,7 @@ ackAnyImpl( CommsCtxt* comms, XWEnv xwe, XP_Bool force )
|
|||
}
|
||||
COMMS_LOGFF( "sent for %d channels (of %d)", nSent, nSeen );
|
||||
}
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3040,7 +2989,7 @@ validateChannelMessage( CommsCtxt* comms, XWEnv xwe, const CommsAddrRec* addr,
|
|||
|
||||
{
|
||||
AddressRecord* rec;
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
LOG_FUNC();
|
||||
|
||||
rec = getRecordFor( comms, channelNo );
|
||||
|
@ -3067,7 +3016,7 @@ validateChannelMessage( CommsCtxt* comms, XWEnv xwe, const CommsAddrRec* addr,
|
|||
}
|
||||
|
||||
LOG_RETURNF( XP_P, rec );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
return rec;
|
||||
} /* validateChannelMessage */
|
||||
|
||||
|
@ -3083,7 +3032,7 @@ static XP_Bool
|
|||
getCheckChannelSeed( CommsCtxt* comms, XWStreamCtxt* stream, HeaderStuff* stuff )
|
||||
{
|
||||
XP_Bool messageValid;
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
messageValid = stream_gotU16( stream, &stuff->channelNo );
|
||||
if ( messageValid ) {
|
||||
XP_U16 channelSeed = comms_getChannelSeed( comms );
|
||||
|
@ -3107,7 +3056,7 @@ getCheckChannelSeed( CommsCtxt* comms, XWStreamCtxt* stream, HeaderStuff* stuff
|
|||
}
|
||||
}
|
||||
LOG_RETURNF( "%s", boolToStr(messageValid) );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
return messageValid;
|
||||
}
|
||||
|
||||
|
@ -3133,7 +3082,7 @@ parseSmallHeader( CommsCtxt* comms, XWStreamCtxt* msgStream,
|
|||
HeaderStuff* stuff )
|
||||
{
|
||||
XP_Bool messageValid = XP_FALSE;
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
XP_U16 headerLen = stuff->flags >> HEADER_LEN_OFFSET;
|
||||
XP_ASSERT( 0 < headerLen );
|
||||
XP_ASSERT( headerLen <= stream_getSize( msgStream ) );
|
||||
|
@ -3157,7 +3106,7 @@ parseSmallHeader( CommsCtxt* comms, XWStreamCtxt* msgStream,
|
|||
}
|
||||
|
||||
// LOG_RETURNF( "%s", boolToStr(messageValid) );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
return messageValid;
|
||||
}
|
||||
|
||||
|
@ -3166,7 +3115,7 @@ comms_checkIncomingStream( CommsCtxt* comms, XWEnv xwe, XWStreamCtxt* stream,
|
|||
const CommsAddrRec* retAddr, CommsMsgState* state )
|
||||
{
|
||||
XP_Bool messageValid = XP_FALSE;
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
XP_ASSERT( !!retAddr ); /* for now */
|
||||
XP_MEMSET( state, 0, sizeof(*state) );
|
||||
#ifdef DEBUG
|
||||
|
@ -3276,7 +3225,7 @@ comms_checkIncomingStream( CommsCtxt* comms, XWEnv xwe, XWStreamCtxt* stream,
|
|||
|
||||
}
|
||||
LOG_RETURNF( "%s (len: %d; sum: %s)", boolToStr(messageValid), state->len, state->sum );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
return messageValid;
|
||||
} /* comms_checkIncomingStream */
|
||||
|
||||
|
@ -3284,7 +3233,7 @@ void
|
|||
comms_msgProcessed( CommsCtxt* comms, XWEnv xwe,
|
||||
CommsMsgState* state, XP_Bool rejected )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
assertQueueOk( comms );
|
||||
|
||||
COMMS_LOGFF( "rec: %p; len: %d; sum: %s; id: %d; rejected: %s", state->rec,
|
||||
|
@ -3319,7 +3268,7 @@ comms_msgProcessed( CommsCtxt* comms, XWEnv xwe,
|
|||
#ifdef DEBUG
|
||||
comms->processingMsg = XP_FALSE;
|
||||
#endif
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
|
@ -3414,7 +3363,7 @@ comms_gameJoined( CommsCtxt* comms, XWEnv xwe, const XP_UCHAR* connname, XWHostI
|
|||
static void
|
||||
sendEmptyMsg( CommsCtxt* comms, XWEnv xwe, AddressRecord* rec )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
MsgQueueElem* elem = makeElemWithID( comms, xwe, 0 /* msgID */,
|
||||
rec, rec? rec->channelNo : 0, NULL );
|
||||
XP_ASSERT( !!elem );
|
||||
|
@ -3422,7 +3371,7 @@ sendEmptyMsg( CommsCtxt* comms, XWEnv xwe, AddressRecord* rec )
|
|||
if ( !!elem ) {
|
||||
sendMsg( comms, xwe, elem, COMMS_CONN_NONE );
|
||||
}
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
} /* sendEmptyMsg */
|
||||
#endif
|
||||
|
||||
|
@ -3508,7 +3457,7 @@ statsProc( MsgQueueElem* elem, void* closure )
|
|||
void
|
||||
comms_getStats( RELCONST CommsCtxt* comms, XWStreamCtxt* stream )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
WITH_MUTEX(&comms->mutex);
|
||||
XP_UCHAR buf[100];
|
||||
|
||||
XP_SNPRINTF( (XP_UCHAR*)buf, sizeof(buf),
|
||||
|
@ -3535,7 +3484,7 @@ comms_getStats( RELCONST CommsCtxt* comms, XWStreamCtxt* stream )
|
|||
rec->lastMsgRcd );
|
||||
stream_catString( stream, buf );
|
||||
}
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
} /* comms_getStats */
|
||||
|
||||
void
|
||||
|
@ -3562,7 +3511,7 @@ rememberChannelAddress( CommsCtxt* comms, XP_PlayerAddr channelNo,
|
|||
XWHostID hostID, const CommsAddrRec* addr, XP_U16 flags )
|
||||
{
|
||||
AddressRecord* rec = NULL;
|
||||
COMMS_MUTEX_LOCK( comms );
|
||||
WITH_MUTEX( &comms->mutex);
|
||||
CNO_FMT( cbuf, channelNo );
|
||||
COMMS_LOGFF( "(%s)", cbuf );
|
||||
listRecs( comms, "entering rememberChannelAddress" );
|
||||
|
@ -3600,7 +3549,7 @@ rememberChannelAddress( CommsCtxt* comms, XP_PlayerAddr channelNo,
|
|||
}
|
||||
}
|
||||
listRecs( comms, "leaving rememberChannelAddress()" );
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
return rec;
|
||||
} /* rememberChannelAddress */
|
||||
|
||||
|
@ -3688,7 +3637,7 @@ static void
|
|||
augmentChannelAddr( CommsCtxt* comms, AddressRecord* const rec,
|
||||
const CommsAddrRec* addr, XWHostID hostID )
|
||||
{
|
||||
COMMS_MUTEX_LOCK( comms );
|
||||
WITH_MUTEX( &comms->mutex);
|
||||
augmentAddrIntrnl( comms, &rec->addr, addr, XP_TRUE );
|
||||
#ifdef XWFEATURE_RELAY
|
||||
if ( addr_hasType( &rec->addr, COMMS_CONN_RELAY ) ) {
|
||||
|
@ -3709,7 +3658,7 @@ augmentChannelAddr( CommsCtxt* comms, AddressRecord* const rec,
|
|||
}
|
||||
}
|
||||
#endif
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
END_WITH_MUTEX();
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
|
|
|
@ -82,6 +82,7 @@ COMMON4 = \
|
|||
$(COMMONOBJDIR)/dragdrpp.o \
|
||||
$(COMMONOBJDIR)/memstream.o \
|
||||
$(COMMONOBJDIR)/comms.o \
|
||||
$(COMMONOBJDIR)/xwmutex.o \
|
||||
$(COMMONOBJDIR)/nli.o \
|
||||
$(COMMONOBJDIR)/mempool.o \
|
||||
|
||||
|
|
36
xwords4/common/xwmutex.c
Normal file
36
xwords4/common/xwmutex.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 2024 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "xwmutex.h"
|
||||
|
||||
void
|
||||
initMutex( pthread_mutex_t* mutex, XP_Bool recursive )
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
int ret = pthread_mutexattr_init(&attr);
|
||||
XP_ASSERT(0 == ret);
|
||||
if ( recursive ) {
|
||||
ret = pthread_mutexattr_settype(&attr,
|
||||
PTHREAD_MUTEX_RECURSIVE);
|
||||
XP_ASSERT(0 == ret);
|
||||
}
|
||||
pthread_mutex_init( mutex, &attr );
|
||||
ret = pthread_mutexattr_destroy(&attr);
|
||||
XP_ASSERT(0 == ret);
|
||||
}
|
63
xwords4/common/xwmutex.h
Normal file
63
xwords4/common/xwmutex.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 2024 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _XWMUTEX_H_
|
||||
#define _XWMUTEX_H_
|
||||
|
||||
#include <pthread.h>
|
||||
#include "xptypes.h"
|
||||
|
||||
#define WITH_MUTEX_LOCK_DEBUG(MUTEX) { \
|
||||
pthread_mutex_t* _mutex = (MUTEX); \
|
||||
time_t startTime = time(NULL); \
|
||||
pthread_mutex_lock(_mutex); \
|
||||
time_t gotItTime = time(NULL); \
|
||||
time_t _elapsed = gotItTime-startTime; \
|
||||
if ( 0 < _elapsed ) { \
|
||||
XP_LOGFF("took %lds to get mutex", _elapsed); \
|
||||
} \
|
||||
|
||||
#define WITH_MUTEX_UNLOCK_DEBUG() \
|
||||
time_t unlockTime = time(NULL); \
|
||||
_elapsed = unlockTime-gotItTime; \
|
||||
if ( 0 < _elapsed ) { \
|
||||
XP_LOGFF("held mutex for %lds", _elapsed); \
|
||||
} \
|
||||
pthread_mutex_unlock(_mutex); \
|
||||
} \
|
||||
|
||||
#define WITH_MUTEX_LOCK_RELEASE(COMMS) { \
|
||||
CommsCtxt* _comms = COMMS; \
|
||||
pthread_mutex_lock(&_comms->mutex); \
|
||||
|
||||
#define WITH_MUTEX_UNLOCK_RELEASE() \
|
||||
pthread_mutex_unlock(&_comms->mutex); \
|
||||
} \
|
||||
|
||||
#ifdef DEBUG
|
||||
#define WITH_MUTEX WITH_MUTEX_LOCK_DEBUG
|
||||
#define END_WITH_MUTEX WITH_MUTEX_UNLOCK_DEBUG
|
||||
#else
|
||||
#define WITH_MUTEX WITH_MUTEX_LOCK_RELEASE
|
||||
#define END_WITH_MUTEX WITH_MUTEX_UNLOCK_RELEASE
|
||||
#endif
|
||||
|
||||
void initMutex( pthread_mutex_t* mutex, XP_Bool recursive );
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue