mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-16 15:41:16 +01:00
use a hash of lists rather than a single list to store pending
background messages to fix assertion failure when more than two devices are playing: messages must be sent grouped by relayID.
This commit is contained in:
parent
eec83fe5b6
commit
9115b344fb
2 changed files with 33 additions and 27 deletions
|
@ -440,32 +440,35 @@ formatConfirmTrade( const XP_UCHAR** tiles, XP_U16 nTiles,
|
||||||
|
|
||||||
typedef struct _MsgRec {
|
typedef struct _MsgRec {
|
||||||
XP_U8* msg;
|
XP_U8* msg;
|
||||||
XP_U16 len;
|
XP_U16 msglen;
|
||||||
gchar* relayID;
|
|
||||||
} MsgRec;
|
} MsgRec;
|
||||||
|
|
||||||
void
|
void
|
||||||
initNoConnStorage( CommonGlobals* cGlobals )
|
initNoConnStorage( CommonGlobals* cGlobals )
|
||||||
{
|
{
|
||||||
XP_ASSERT( NULL == cGlobals->noConnMsgs );
|
XP_ASSERT( NULL == cGlobals->noConnMsgs );
|
||||||
cGlobals->noConnMsgs = (GSList*)-1; /* -1 is flag meaning "use me" */
|
cGlobals->noConnMsgs = g_hash_table_new( g_str_hash, g_str_equal );
|
||||||
}
|
}
|
||||||
|
|
||||||
XP_Bool
|
XP_Bool
|
||||||
storeNoConnMsg( CommonGlobals* cGlobals, const XP_U8* msg, XP_U16 len,
|
storeNoConnMsg( CommonGlobals* cGlobals, const XP_U8* msg, XP_U16 msglen,
|
||||||
const XP_UCHAR* relayID )
|
const XP_UCHAR* relayID )
|
||||||
{
|
{
|
||||||
|
XP_ASSERT( 0 < msglen );
|
||||||
XP_Bool inUse = NULL != cGlobals->noConnMsgs;
|
XP_Bool inUse = NULL != cGlobals->noConnMsgs;
|
||||||
if ( inUse ) {
|
if ( inUse ) {
|
||||||
if ( (GSList*)-1 == cGlobals->noConnMsgs ) {
|
GSList* list = g_hash_table_lookup( cGlobals->noConnMsgs, relayID );
|
||||||
cGlobals->noConnMsgs = NULL;
|
gboolean missing = NULL == list;
|
||||||
}
|
|
||||||
MsgRec* msgrec = g_malloc( sizeof(*msgrec) );
|
MsgRec* msgrec = g_malloc( sizeof(*msgrec) );
|
||||||
msgrec->msg = g_malloc( len );
|
msgrec->msg = g_malloc( msglen );
|
||||||
XP_MEMCPY( msgrec->msg, msg, len );
|
XP_MEMCPY( msgrec->msg, msg, msglen );
|
||||||
msgrec->len = len;
|
msgrec->msglen = msglen;
|
||||||
msgrec->relayID = g_strdup( relayID );
|
list = g_slist_append( list, msgrec );
|
||||||
cGlobals->noConnMsgs = g_slist_append( cGlobals->noConnMsgs, msgrec );
|
if ( missing ) {
|
||||||
|
gchar* key = g_strdup( relayID ); /* will leak */
|
||||||
|
g_hash_table_insert( cGlobals->noConnMsgs, key, list );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return inUse;
|
return inUse;
|
||||||
}
|
}
|
||||||
|
@ -473,12 +476,14 @@ storeNoConnMsg( CommonGlobals* cGlobals, const XP_U8* msg, XP_U16 len,
|
||||||
void
|
void
|
||||||
writeNoConnMsgs( CommonGlobals* cGlobals, int fd )
|
writeNoConnMsgs( CommonGlobals* cGlobals, int fd )
|
||||||
{
|
{
|
||||||
guint nMsgs = (GSList*)-1 == cGlobals->noConnMsgs ?
|
GHashTable* hash = cGlobals->noConnMsgs;
|
||||||
0 : g_slist_length( cGlobals->noConnMsgs );
|
GList* keys = g_hash_table_get_keys( hash );
|
||||||
if ( 0 < nMsgs ) {
|
GList* iter;
|
||||||
gchar relayID[128] = {0};
|
for ( iter = keys; !!iter; iter = iter->next ) {
|
||||||
|
XP_UCHAR* relayID = (XP_UCHAR*)iter->data;
|
||||||
strcpy( relayID, ((MsgRec*)(cGlobals->noConnMsgs->data))->relayID );
|
GSList* list = (GSList*)g_hash_table_lookup( hash, relayID );
|
||||||
|
guint nMsgs = g_slist_length( list );
|
||||||
|
XP_ASSERT( 0 < nMsgs );
|
||||||
|
|
||||||
XWStreamCtxt* stream =
|
XWStreamCtxt* stream =
|
||||||
mem_stream_make( MPPARM(cGlobals->params->util->mpool)
|
mem_stream_make( MPPARM(cGlobals->params->util->mpool)
|
||||||
|
@ -491,17 +496,14 @@ writeNoConnMsgs( CommonGlobals* cGlobals, int fd )
|
||||||
|
|
||||||
int ii;
|
int ii;
|
||||||
for ( ii = 0; ii < nMsgs; ++ii ) {
|
for ( ii = 0; ii < nMsgs; ++ii ) {
|
||||||
MsgRec* rec = g_slist_nth_data( cGlobals->noConnMsgs, ii );
|
MsgRec* rec = g_slist_nth_data( list, ii );
|
||||||
stream_putU16( stream, rec->len );
|
stream_putU16( stream, rec->msglen );
|
||||||
stream_putBytes( stream, rec->msg, rec->len );
|
stream_putBytes( stream, rec->msg, rec->msglen );
|
||||||
|
|
||||||
g_free( rec->msg );
|
g_free( rec->msg );
|
||||||
XP_ASSERT( 0 == strcmp( relayID, rec->relayID ) );
|
|
||||||
g_free( rec->relayID );
|
|
||||||
g_free( rec );
|
g_free( rec );
|
||||||
}
|
}
|
||||||
g_slist_free( cGlobals->noConnMsgs );
|
g_slist_free( list );
|
||||||
cGlobals->noConnMsgs = NULL;
|
|
||||||
|
|
||||||
XP_U16 siz = stream_getSize( stream );
|
XP_U16 siz = stream_getSize( stream );
|
||||||
/* XP_U8 buf[siz]; */
|
/* XP_U8 buf[siz]; */
|
||||||
|
@ -513,6 +515,9 @@ writeNoConnMsgs( CommonGlobals* cGlobals, int fd )
|
||||||
XP_ASSERT( nwritten == siz );
|
XP_ASSERT( nwritten == siz );
|
||||||
stream_destroy( stream );
|
stream_destroy( stream );
|
||||||
}
|
}
|
||||||
|
g_list_free( keys );
|
||||||
|
g_hash_table_unref( hash );
|
||||||
|
cGlobals->noConnMsgs = NULL;
|
||||||
} /* writeNoConnMsgs */
|
} /* writeNoConnMsgs */
|
||||||
|
|
||||||
#ifdef TEXT_MODEL
|
#ifdef TEXT_MODEL
|
||||||
|
|
|
@ -163,7 +163,8 @@ struct CommonGlobals {
|
||||||
AddAcceptorFunc addAcceptor;
|
AddAcceptorFunc addAcceptor;
|
||||||
Acceptor acceptor;
|
Acceptor acceptor;
|
||||||
|
|
||||||
GSList* noConnMsgs;
|
/* hash by relayID of lists of messages */
|
||||||
|
GHashTable* noConnMsgs;
|
||||||
|
|
||||||
#ifdef XWFEATURE_RELAY
|
#ifdef XWFEATURE_RELAY
|
||||||
int socket; /* relay */
|
int socket; /* relay */
|
||||||
|
|
Loading…
Reference in a new issue