mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-15 20:48:00 +01:00
pool acks and send using a timer (untested on Android)
This commit is contained in:
parent
faf398790c
commit
c45638e037
4 changed files with 80 additions and 45 deletions
|
@ -29,6 +29,7 @@
|
||||||
#include "nli.h"
|
#include "nli.h"
|
||||||
#include "dbgutil.h"
|
#include "dbgutil.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
|
#include "xwmutex.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# define MAGIC_INITED 0x8283413F
|
# define MAGIC_INITED 0x8283413F
|
||||||
|
@ -73,7 +74,13 @@ typedef struct _DevCtxt {
|
||||||
XP_U16 devCount;
|
XP_U16 devCount;
|
||||||
WSData* webSendData;
|
WSData* webSendData;
|
||||||
XP_U32 mWebSendKey;
|
XP_U32 mWebSendKey;
|
||||||
pthread_mutex_t webSendMutex;
|
MutexState webSendMutex;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
MutexState mutex;
|
||||||
|
cJSON* msgs; /* pending acks saved here */
|
||||||
|
TimerKey key;
|
||||||
|
} ackTimer;
|
||||||
|
|
||||||
PhoniesDataCodes* pd;
|
PhoniesDataCodes* pd;
|
||||||
|
|
||||||
|
@ -538,41 +545,64 @@ dispatchMsgs( XW_DUtilCtxt* dutil, XWEnv xwe, XP_U8 proto, XWStreamCtxt* stream,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
onAckSendTimer( void* closure, XWEnv xwe, XP_Bool fired )
|
||||||
|
{
|
||||||
|
XP_LOGFF( "(fired: %s)", boolToStr(fired) );
|
||||||
|
XW_DUtilCtxt* dutil = (XW_DUtilCtxt*)closure;
|
||||||
|
DevCtxt* dc = load( dutil, xwe );
|
||||||
|
cJSON* ackMsgs;
|
||||||
|
WITH_MUTEX( &dc->ackTimer.mutex );
|
||||||
|
ackMsgs = dc->ackTimer.msgs;
|
||||||
|
dc->ackTimer.msgs = NULL;
|
||||||
|
dc->ackTimer.key = 0;
|
||||||
|
END_WITH_MUTEX();
|
||||||
|
|
||||||
|
XP_ASSERT( 0 < cJSON_GetArraySize( ackMsgs ) );
|
||||||
|
|
||||||
|
if ( fired ) {
|
||||||
|
cJSON* params = cJSON_CreateObject();
|
||||||
|
cJSON_AddItemToObject( params, "msgs", ackMsgs );
|
||||||
|
dutil_sendViaWeb( dutil, xwe, 0, "ack2", params );
|
||||||
|
cJSON_Delete( params );
|
||||||
|
} else {
|
||||||
|
XP_LOGFF( "Dropping ack messages -- but should store them!" );
|
||||||
|
cJSON_Delete( ackMsgs );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setAckSendTimerLocked( XW_DUtilCtxt* dutil, XWEnv xwe, DevCtxt* dc )
|
||||||
|
{
|
||||||
|
if ( 0 == dc->ackTimer.key ) {
|
||||||
|
XP_U32 inWhenMS = 10 * 1000;
|
||||||
|
dc->ackTimer.key = tmr_set( dutil, xwe, inWhenMS, onAckSendTimer,
|
||||||
|
dutil );
|
||||||
|
XP_ASSERT( 0 != dc->ackTimer.key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ackMQTTMsg( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* topic,
|
ackMQTTMsg( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* topic,
|
||||||
XP_U32 gameID, const XP_U8* buf, XP_U16 len )
|
XP_U32 gameID, const XP_U8* buf, XP_U16 len )
|
||||||
{
|
{
|
||||||
cJSON* params = cJSON_CreateObject();
|
cJSON* msg = cJSON_CreateObject();
|
||||||
#if 1
|
cJSON_AddStringToObject( msg, "topic", topic );
|
||||||
cJSON* msgs = cJSON_CreateArray();
|
|
||||||
/* This belongs in a loop */
|
|
||||||
{
|
|
||||||
cJSON* msg = cJSON_CreateObject();
|
|
||||||
cJSON_AddStringToObject( msg, "topic", topic );
|
|
||||||
|
|
||||||
Md5SumBuf sb;
|
|
||||||
dutil_md5sum( dutil, xwe, buf, len, &sb );
|
|
||||||
cJSON_AddStringToObject( msg, "sum", sb.buf );
|
|
||||||
|
|
||||||
cJSON_AddNumberToObject( msg, "gid", gameID );
|
|
||||||
|
|
||||||
cJSON_AddItemToArray(msgs, msg);
|
|
||||||
}
|
|
||||||
cJSON_AddItemToObject(params, "msgs", msgs );
|
|
||||||
|
|
||||||
dutil_sendViaWeb( dutil, xwe, 0, "ack2", params );
|
|
||||||
#else
|
|
||||||
cJSON_AddStringToObject( params, "topic", topic );
|
|
||||||
|
|
||||||
Md5SumBuf sb;
|
Md5SumBuf sb;
|
||||||
dutil_md5sum( dutil, xwe, buf, len, &sb );
|
dutil_md5sum( dutil, xwe, buf, len, &sb );
|
||||||
cJSON_AddStringToObject( params, "sum", sb.buf );
|
cJSON_AddStringToObject( msg, "sum", sb.buf );
|
||||||
|
|
||||||
cJSON_AddNumberToObject( params, "gid", gameID );
|
cJSON_AddNumberToObject( msg, "gid", gameID );
|
||||||
|
|
||||||
dutil_sendViaWeb( dutil, xwe, 0, "ack", params );
|
DevCtxt* dc = load( dutil, xwe );
|
||||||
#endif
|
WITH_MUTEX( &dc->ackTimer.mutex );
|
||||||
cJSON_Delete( params );
|
if ( !dc->ackTimer.msgs ) {
|
||||||
|
dc->ackTimer.msgs = cJSON_CreateArray();
|
||||||
|
}
|
||||||
|
cJSON_AddItemToArray( dc->ackTimer.msgs, msg );
|
||||||
|
setAckSendTimerLocked( dutil, xwe, dc );
|
||||||
|
END_WITH_MUTEX();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -674,14 +704,14 @@ popForKey( XW_DUtilCtxt* dutil, XWEnv xwe, XP_U32 key )
|
||||||
WSData* item = NULL;
|
WSData* item = NULL;
|
||||||
DevCtxt* dc = load( dutil, xwe );
|
DevCtxt* dc = load( dutil, xwe );
|
||||||
|
|
||||||
pthread_mutex_lock( &dc->webSendMutex );
|
WITH_MUTEX(&dc->webSendMutex);
|
||||||
|
|
||||||
GetByKeyData gbkd = { .resultKey = key, };
|
GetByKeyData gbkd = { .resultKey = key, };
|
||||||
dc->webSendData = (WSData*)dll_map( &dc->webSendData->links,
|
dc->webSendData = (WSData*)dll_map( &dc->webSendData->links,
|
||||||
getByKeyProc, NULL, &gbkd );
|
getByKeyProc, NULL, &gbkd );
|
||||||
item = gbkd.found;
|
item = gbkd.found;
|
||||||
|
|
||||||
pthread_mutex_unlock( &dc->webSendMutex );
|
END_WITH_MUTEX();
|
||||||
XP_LOGFFV( "(key: %d) => %p", key, item );
|
XP_LOGFFV( "(key: %d) => %p", key, item );
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -690,11 +720,11 @@ static XP_U32
|
||||||
addWithKey( XW_DUtilCtxt* dutil, XWEnv xwe, WSData* wsdp )
|
addWithKey( XW_DUtilCtxt* dutil, XWEnv xwe, WSData* wsdp )
|
||||||
{
|
{
|
||||||
DevCtxt* dc = load( dutil, xwe );
|
DevCtxt* dc = load( dutil, xwe );
|
||||||
pthread_mutex_lock( &dc->webSendMutex );
|
WITH_MUTEX(&dc->webSendMutex);
|
||||||
wsdp->resultKey = ++dc->mWebSendKey;
|
wsdp->resultKey = ++dc->mWebSendKey;
|
||||||
dc->webSendData = (WSData*)
|
dc->webSendData = (WSData*)
|
||||||
dll_insert( &dc->webSendData->links, &wsdp->links, NULL );
|
dll_insert( &dc->webSendData->links, &wsdp->links, NULL );
|
||||||
pthread_mutex_unlock( &dc->webSendMutex );
|
END_WITH_MUTEX();
|
||||||
XP_LOGFFV( "(%p) => %d", wsdp, wsdp->resultKey );
|
XP_LOGFFV( "(%p) => %d", wsdp, wsdp->resultKey );
|
||||||
return wsdp->resultKey;
|
return wsdp->resultKey;
|
||||||
}
|
}
|
||||||
|
@ -752,9 +782,9 @@ dvc_onWebSendResult( XW_DUtilCtxt* dutil, XWEnv xwe, XP_U32 resultKey,
|
||||||
static void
|
static void
|
||||||
freeWSState( XW_DUtilCtxt* dutil, DevCtxt* dc )
|
freeWSState( XW_DUtilCtxt* dutil, DevCtxt* dc )
|
||||||
{
|
{
|
||||||
pthread_mutex_lock( &dc->webSendMutex );
|
WITH_MUTEX( &dc->webSendMutex );
|
||||||
dll_removeAll( &dc->webSendData->links, delWSDatum, dutil );
|
dll_removeAll( &dc->webSendData->links, delWSDatum, dutil );
|
||||||
pthread_mutex_unlock( &dc->webSendMutex );
|
END_WITH_MUTEX();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _PhoniesMapState {
|
typedef struct _PhoniesMapState {
|
||||||
|
@ -1147,7 +1177,9 @@ dvc_init( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||||||
DevCtxt* dc = dutil->devCtxt = XP_CALLOC( dutil->mpool, sizeof(*dc) );
|
DevCtxt* dc = dutil->devCtxt = XP_CALLOC( dutil->mpool, sizeof(*dc) );
|
||||||
dc->webSendData = NULL;
|
dc->webSendData = NULL;
|
||||||
dc->mWebSendKey = 0;
|
dc->mWebSendKey = 0;
|
||||||
pthread_mutex_init( &dc->webSendMutex, NULL );
|
|
||||||
|
mtx_init( &dc->webSendMutex, XP_FALSE );
|
||||||
|
mtx_init( &dc->ackTimer.mutex, XP_FALSE );
|
||||||
|
|
||||||
loadPhoniesData( dutil, xwe, dc );
|
loadPhoniesData( dutil, xwe, dc );
|
||||||
|
|
||||||
|
@ -1161,10 +1193,10 @@ void
|
||||||
dvc_cleanup( XW_DUtilCtxt* dutil, XWEnv xwe )
|
dvc_cleanup( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||||||
{
|
{
|
||||||
DevCtxt* dc = freePhonyState( dutil, xwe );
|
DevCtxt* dc = freePhonyState( dutil, xwe );
|
||||||
|
|
||||||
freeWSState( dutil, dc );
|
freeWSState( dutil, dc );
|
||||||
|
|
||||||
pthread_mutex_destroy( &dc->webSendMutex );
|
mtx_destroy( &dc->webSendMutex );
|
||||||
|
mtx_destroy( &dc->ackTimer.mutex );
|
||||||
|
|
||||||
XP_FREEP( dutil->mpool, &dc );
|
XP_FREEP( dutil->mpool, &dc );
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,7 +300,7 @@ pushEntry( StackCtxt* stack, const StackEntry* entry )
|
||||||
#ifdef DEBUG_HASHING
|
#ifdef DEBUG_HASHING
|
||||||
XP_U32 origHash = stack_getHash( stack );
|
XP_U32 origHash = stack_getHash( stack );
|
||||||
|
|
||||||
StackEntry prevTop;
|
StackEntry prevTop = {};
|
||||||
if ( 1 < stack->nPlayers &&
|
if ( 1 < stack->nPlayers &&
|
||||||
stack_getNthEntry( stack, stack->nEntries - 1, &prevTop ) ) {
|
stack_getNthEntry( stack, stack->nEntries - 1, &prevTop ) ) {
|
||||||
XP_ASSERT( stack->inDuplicateMode || prevTop.playerNum != entry->playerNum );
|
XP_ASSERT( stack->inDuplicateMode || prevTop.playerNum != entry->playerNum );
|
||||||
|
|
|
@ -33,8 +33,8 @@ typedef struct StatsState {
|
||||||
|
|
||||||
static const XP_UCHAR* STATtoStr(STAT stat);
|
static const XP_UCHAR* STATtoStr(STAT stat);
|
||||||
static XP_U32* loadCounts( XW_DUtilCtxt* dutil, XWEnv xwe );
|
static XP_U32* loadCounts( XW_DUtilCtxt* dutil, XWEnv xwe );
|
||||||
static void storeCounts( XW_DUtilCtxt* dutil, XWEnv xwe );
|
static void storeCountsLocked( XW_DUtilCtxt* dutil, XWEnv xwe );
|
||||||
static void setStoreTimer( XW_DUtilCtxt* dutil, XWEnv xwe );
|
static void setStoreTimerLocked( XW_DUtilCtxt* dutil, XWEnv xwe );
|
||||||
|
|
||||||
void
|
void
|
||||||
sts_init( XW_DUtilCtxt* dutil )
|
sts_init( XW_DUtilCtxt* dutil )
|
||||||
|
@ -66,7 +66,7 @@ sts_increment( XW_DUtilCtxt* dutil, XWEnv xwe, STAT stat )
|
||||||
}
|
}
|
||||||
++ss->statsVals[stat];
|
++ss->statsVals[stat];
|
||||||
|
|
||||||
setStoreTimer( dutil, xwe );
|
setStoreTimerLocked( dutil, xwe );
|
||||||
END_WITH_MUTEX();
|
END_WITH_MUTEX();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ sts_clearAll( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||||||
|
|
||||||
ss->statsVals
|
ss->statsVals
|
||||||
= XP_CALLOC( dutil->mpool, sizeof(*ss->statsVals) * STAT_NSTATS );
|
= XP_CALLOC( dutil->mpool, sizeof(*ss->statsVals) * STAT_NSTATS );
|
||||||
storeCounts( dutil, xwe );
|
storeCountsLocked( dutil, xwe );
|
||||||
END_WITH_MUTEX();
|
END_WITH_MUTEX();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ STATtoStr(STAT stat)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
storeCounts( XW_DUtilCtxt* dutil, XWEnv xwe )
|
storeCountsLocked( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||||||
{
|
{
|
||||||
StatsState* ss = dutil->statsState;
|
StatsState* ss = dutil->statsState;
|
||||||
XP_ASSERT( !!ss );
|
XP_ASSERT( !!ss );
|
||||||
|
@ -188,7 +188,7 @@ onStoreTimer( void* closure, XWEnv xwe, XP_Bool fired )
|
||||||
XP_ASSERT( !!ss );
|
XP_ASSERT( !!ss );
|
||||||
|
|
||||||
WITH_MUTEX( &ss->mutex );
|
WITH_MUTEX( &ss->mutex );
|
||||||
storeCounts( dutil, xwe );
|
storeCountsLocked( dutil, xwe );
|
||||||
ss->timerSet = XP_FALSE;
|
ss->timerSet = XP_FALSE;
|
||||||
END_WITH_MUTEX();
|
END_WITH_MUTEX();
|
||||||
LOG_RETURN_VOID();
|
LOG_RETURN_VOID();
|
||||||
|
@ -196,7 +196,7 @@ onStoreTimer( void* closure, XWEnv xwe, XP_Bool fired )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setStoreTimer( XW_DUtilCtxt* dutil, XWEnv xwe )
|
setStoreTimerLocked( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||||||
{
|
{
|
||||||
#ifdef DUTIL_TIMERS
|
#ifdef DUTIL_TIMERS
|
||||||
StatsState* ss = dutil->statsState;
|
StatsState* ss = dutil->statsState;
|
||||||
|
|
|
@ -245,7 +245,8 @@ class Device():
|
||||||
# called by thread proc
|
# called by thread proc
|
||||||
def _launchProc(self):
|
def _launchProc(self):
|
||||||
assert not self.endTime
|
assert not self.endTime
|
||||||
self.endTime = datetime.datetime.now() + datetime.timedelta(seconds = 5)
|
self.endTime = datetime.datetime.now() + \
|
||||||
|
datetime.timedelta(seconds = self.args.MIN_APP_LIFE)
|
||||||
args = [ self.script, '--close-stdin', '--skip-user-errors' ]
|
args = [ self.script, '--close-stdin', '--skip-user-errors' ]
|
||||||
if not self.args.USE_GTK: args.append('--curses')
|
if not self.args.USE_GTK: args.append('--curses')
|
||||||
|
|
||||||
|
@ -913,6 +914,8 @@ def mkParser():
|
||||||
|
|
||||||
parser.add_argument('--timer-seconds', dest='TIMER_SECS', default=10, type=int,
|
parser.add_argument('--timer-seconds', dest='TIMER_SECS', default=10, type=int,
|
||||||
help='Enable game timer with game this many seconds long')
|
help='Enable game timer with game this many seconds long')
|
||||||
|
parser.add_argument('--min-app-life', dest='MIN_APP_LIFE', default=5, type=int,
|
||||||
|
help='Minimum number of seconds app will run after each launch')
|
||||||
|
|
||||||
parser.add_argument('--with-sms', dest = 'WITH_SMS', action = 'store_true')
|
parser.add_argument('--with-sms', dest = 'WITH_SMS', action = 'store_true')
|
||||||
parser.add_argument('--without-sms', dest = 'WITH_SMS', default = False, action = 'store_false')
|
parser.add_argument('--without-sms', dest = 'WITH_SMS', default = False, action = 'store_false')
|
||||||
|
|
Loading…
Add table
Reference in a new issue