mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-26 09:58:20 +01:00
add util_clearTimer, implement on all platforms, and call when closing
comms to fix crash on Wince when timer fired after comms had been deleted. The closure stored and passed in was no longer a valid ptr.
This commit is contained in:
parent
f8848321c4
commit
a13e1d6488
8 changed files with 86 additions and 36 deletions
|
@ -336,7 +336,7 @@ set_reset_timer( CommsCtxt* comms )
|
|||
/* This timer is allowed to overwrite a heartbeat timer, but not
|
||||
vice-versa. Make sure we can restart it. */
|
||||
comms->hbTimerPending = XP_FALSE;
|
||||
util_setTimer( comms->util, TIMER_COMMS, 15, /* five seconds */
|
||||
util_setTimer( comms->util, TIMER_COMMS, 15,
|
||||
p_comms_resetTimer, comms );
|
||||
comms->reconTimerPending = XP_TRUE;
|
||||
}
|
||||
|
@ -345,6 +345,7 @@ void
|
|||
comms_transportFailed( CommsCtxt* comms )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XP_ASSERT( !!comms );
|
||||
if ( COMMS_CONN_RELAY == comms->addr.conType ) {
|
||||
relayDisconnect( comms );
|
||||
|
||||
|
@ -364,6 +365,8 @@ comms_destroy( CommsCtxt* comms )
|
|||
cleanupInternal( comms );
|
||||
cleanupAddrRecs( comms );
|
||||
|
||||
util_clearTimer( comms->util, TIMER_COMMS );
|
||||
|
||||
XP_FREE( comms->mpool, comms );
|
||||
} /* comms_destroy */
|
||||
|
||||
|
@ -536,6 +539,7 @@ setDoHeartbeat( CommsCtxt* comms )
|
|||
void
|
||||
comms_start( CommsCtxt* comms )
|
||||
{
|
||||
XP_ASSERT( !!comms );
|
||||
setDoHeartbeat( comms );
|
||||
sendConnect( comms, XP_FALSE );
|
||||
} /* comms_start */
|
||||
|
@ -807,6 +811,7 @@ makeElemWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
|
|||
XP_S16
|
||||
comms_send( CommsCtxt* comms, XWStreamCtxt* stream )
|
||||
{
|
||||
XP_ASSERT( !!comms );
|
||||
XP_PlayerAddr channelNo = stream_getAddress( stream );
|
||||
AddressRecord* rec = getRecordFor( comms, NULL, channelNo );
|
||||
MsgID msgID = (!!rec)? ++rec->nextMsgID : 0;
|
||||
|
@ -988,6 +993,7 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
|
|||
XP_S16
|
||||
comms_resendAll( CommsCtxt* comms )
|
||||
{
|
||||
XP_ASSERT( !!comms );
|
||||
MsgQueueElem* msg;
|
||||
XP_S16 result = 0;
|
||||
|
||||
|
@ -1359,6 +1365,7 @@ XP_Bool
|
|||
comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
||||
const CommsAddrRec* retAddr )
|
||||
{
|
||||
XP_ASSERT( !!comms );
|
||||
XP_Bool messageValid = XP_FALSE;
|
||||
XWHostID senderID = 0; /* unset; default for non-relay cases */
|
||||
XP_Bool usingRelay = XP_FALSE;
|
||||
|
|
|
@ -138,6 +138,7 @@ typedef struct UtilVtable {
|
|||
|
||||
void (*m_util_setTimer)( XW_UtilCtxt* uc, XWTimerReason why, XP_U16 when,
|
||||
XWTimerProc proc, void* closure );
|
||||
void (*m_util_clearTimer)( XW_UtilCtxt* uc, XWTimerReason why );
|
||||
|
||||
void (*m_util_requestTime)( XW_UtilCtxt* uc );
|
||||
|
||||
|
@ -226,6 +227,8 @@ struct XW_UtilCtxt {
|
|||
|
||||
#define util_setTimer( uc, why, when, proc, clos ) \
|
||||
(uc)->vtable->m_util_setTimer((uc),(why),(when),(proc),(clos))
|
||||
#define util_clearTimer( uc, why ) \
|
||||
(uc)->vtable->m_util_clearTimer((uc),(why))
|
||||
|
||||
#define util_requestTime( uc ) \
|
||||
(uc)->vtable->m_util_requestTime((uc))
|
||||
|
|
|
@ -377,6 +377,13 @@ curses_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why, XP_U16 when,
|
|||
}
|
||||
} /* curses_util_setTimer */
|
||||
|
||||
static void
|
||||
curses_util_clearTimer( XW_UtilCtxt* uc, XWTimerReason why )
|
||||
{
|
||||
CursesAppGlobals* globals = (CursesAppGlobals*)uc->closure;
|
||||
globals->cGlobals.timerInfo[why].proc = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
curses_util_requestTime( XW_UtilCtxt* uc )
|
||||
{
|
||||
|
@ -1291,6 +1298,7 @@ setupCursesUtilCallbacks( CursesAppGlobals* globals, XW_UtilCtxt* util )
|
|||
curses_util_engineProgressCallback;
|
||||
|
||||
util->vtable->m_util_setTimer = curses_util_setTimer;
|
||||
util->vtable->m_util_clearTimer = curses_util_clearTimer;
|
||||
util->vtable->m_util_requestTime = curses_util_requestTime;
|
||||
|
||||
util->closure = globals;
|
||||
|
|
|
@ -1340,6 +1340,13 @@ gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
|||
globals->timerSources[why-1] = newSrc;
|
||||
} /* gtk_util_setTimer */
|
||||
|
||||
static void
|
||||
gtk_util_clearTimer( XW_UtilCtxt* uc, XWTimerReason why )
|
||||
{
|
||||
GtkAppGlobals* globals = (GtkAppGlobals*)uc->closure;
|
||||
globals->cGlobals.timerInfo[why].proc = NULL;
|
||||
}
|
||||
|
||||
static gint
|
||||
idle_func( gpointer data )
|
||||
{
|
||||
|
@ -1633,6 +1640,7 @@ setupGtkUtilCallbacks( GtkAppGlobals* globals, XW_UtilCtxt* util )
|
|||
util->vtable->m_util_engineProgressCallback =
|
||||
gtk_util_engineProgressCallback;
|
||||
util->vtable->m_util_setTimer = gtk_util_setTimer;
|
||||
util->vtable->m_util_clearTimer = gtk_util_clearTimer;
|
||||
util->vtable->m_util_requestTime = gtk_util_requestTime;
|
||||
util->vtable->m_util_warnIllegalWord = gtk_util_warnIllegalWord;
|
||||
util->vtable->m_util_remSelected = gtk_util_remSelected;
|
||||
|
|
|
@ -584,7 +584,11 @@ linuxFireTimer( CommonGlobals* cGlobals, XWTimerReason why )
|
|||
|
||||
tip->proc = NULL;
|
||||
|
||||
(*proc)( closure, why );
|
||||
if ( !!proc ) {
|
||||
(*proc)( closure, why );
|
||||
} else {
|
||||
XP_LOGF( "%s: skipping timer %d; cancelled?", __func__, why );
|
||||
}
|
||||
} /* fireTimer */
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
|
|
|
@ -123,6 +123,7 @@ static XP_Bool palm_util_hiliteCell( XW_UtilCtxt* uc, XP_U16 col,
|
|||
static XP_Bool palm_util_engineProgressCallback( XW_UtilCtxt* uc );
|
||||
static void palm_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why, XP_U16 when,
|
||||
XWTimerProc proc, void* closure );
|
||||
static void palm_util_clearTimer( XW_UtilCtxt* uc, XWTimerReason why );
|
||||
static XP_Bool palm_util_altKeyDown( XW_UtilCtxt* uc );
|
||||
static XP_U32 palm_util_getCurSeconds( XW_UtilCtxt* uc );
|
||||
static void palm_util_requestTime( XW_UtilCtxt* uc );
|
||||
|
@ -664,6 +665,7 @@ initUtilFuncs( PalmAppGlobals* globals )
|
|||
vtable->m_util_hiliteCell = palm_util_hiliteCell;
|
||||
vtable->m_util_engineProgressCallback = palm_util_engineProgressCallback;
|
||||
vtable->m_util_setTimer = palm_util_setTimer;
|
||||
vtable->m_util_clearTimer = palm_util_clearTimer;
|
||||
vtable->m_util_requestTime = palm_util_requestTime;
|
||||
vtable->m_util_altKeyDown = palm_util_altKeyDown;
|
||||
vtable->m_util_getCurSeconds = palm_util_getCurSeconds;
|
||||
|
@ -1572,16 +1574,16 @@ palmFireTimer( PalmAppGlobals* globals, XWTimerReason why )
|
|||
static XP_Bool
|
||||
timeForTimer( PalmAppGlobals* globals, XWTimerReason* why, XP_U32* when )
|
||||
{
|
||||
XP_U16 i;
|
||||
XP_U16 ii;
|
||||
XWTimerReason nextWhy = 0;
|
||||
XP_U32 nextWhen = 0xFFFFFFFF;
|
||||
XP_Bool found;
|
||||
|
||||
for ( i = 1; i < NUM_PALM_TIMERS; ++i ) {
|
||||
if ( (globals->timerProcs[i] != NULL) &&
|
||||
(globals->timerFireAt[i] < nextWhen) ) {
|
||||
nextWhy = i;
|
||||
nextWhen = globals->timerFireAt[i];
|
||||
for ( ii = 1; ii < NUM_PALM_TIMERS; ++ii ) {
|
||||
if ( (globals->timerProcs[ii] != NULL) &&
|
||||
(globals->timerFireAt[ii] < nextWhen) ) {
|
||||
nextWhy = ii;
|
||||
nextWhen = globals->timerFireAt[ii];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3908,6 +3910,13 @@ palm_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
|||
postEmptyEvent( noopEvent );
|
||||
} /* palm_util_setTimer */
|
||||
|
||||
static void
|
||||
palm_util_clearTimer( XW_UtilCtxt* uc, XWTimerReason why )
|
||||
{
|
||||
PalmAppGlobals* globals = (PalmAppGlobals*)uc->closure;
|
||||
globals->timerProcs[why] = NULL;
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
palm_util_altKeyDown( XW_UtilCtxt* XP_UNUSED(uc) )
|
||||
{
|
||||
|
|
|
@ -113,6 +113,7 @@ static XP_Bool ce_util_hiliteCell( XW_UtilCtxt* uc, XP_U16 col,
|
|||
static XP_Bool ce_util_engineProgressCallback( XW_UtilCtxt* uc );
|
||||
static void ce_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why, XP_U16 when,
|
||||
XWTimerProc proc, void* closure);
|
||||
static void ce_util_clearTimer( XW_UtilCtxt* uc, XWTimerReason why );
|
||||
static XP_Bool ce_util_altKeyDown( XW_UtilCtxt* uc );
|
||||
static void ce_util_requestTime( XW_UtilCtxt* uc );
|
||||
static XP_U32 ce_util_getCurSeconds( XW_UtilCtxt* uc );
|
||||
|
@ -360,6 +361,7 @@ ceInitUtilFuncs( CEAppGlobals* globals )
|
|||
vtable->m_util_hiliteCell = ce_util_hiliteCell;
|
||||
vtable->m_util_engineProgressCallback = ce_util_engineProgressCallback;
|
||||
vtable->m_util_setTimer = ce_util_setTimer;
|
||||
vtable->m_util_clearTimer = ce_util_clearTimer;
|
||||
vtable->m_util_altKeyDown = ce_util_altKeyDown;
|
||||
vtable->m_util_requestTime = ce_util_requestTime;
|
||||
vtable->m_util_getCurSeconds = ce_util_getCurSeconds;
|
||||
|
@ -2146,14 +2148,12 @@ static XP_Bool
|
|||
ceFireTimer( CEAppGlobals* globals, XWTimerReason why )
|
||||
{
|
||||
XP_Bool draw = XP_FALSE;
|
||||
XWTimerProc proc;
|
||||
void* closure;
|
||||
TimerData* timer = &globals->timerData[why];
|
||||
XWTimerProc proc = timer->proc;
|
||||
|
||||
proc = globals->timerProcs[why];
|
||||
if ( !!proc ) {
|
||||
globals->timerProcs[why] = NULL;
|
||||
closure = globals->timerClosures[why];
|
||||
draw = (*proc)( closure, why );
|
||||
timer->proc = NULL;
|
||||
draw = (*proc)( timer->closure, why );
|
||||
/* Setting draw after firing timer allows scrolling to happen
|
||||
while pen is held down. This is a hack. Perhaps having
|
||||
the timer proc return whether drawing is needed would be
|
||||
|
@ -2175,21 +2175,14 @@ static XP_Bool
|
|||
checkFireLateKeyTimer( CEAppGlobals* globals )
|
||||
{
|
||||
XP_Bool drop = XP_FALSE;
|
||||
XWTimerReason whys[] = { TIMER_PENDOWN, TIMER_TIMERTICK
|
||||
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
|
||||
, TIMER_COMMS
|
||||
#endif
|
||||
};
|
||||
XWTimerReason why;
|
||||
XP_U32 now = GetCurrentTime();
|
||||
XP_U16 i;
|
||||
|
||||
for ( i = 0; i < sizeof(whys)/sizeof(whys[0]); ++i ) {
|
||||
XWTimerReason why = whys[i];
|
||||
if ( !!globals->timerProcs[why] ) {
|
||||
if ( now >= globals->timerWhens[why] ) {
|
||||
(void)ceFireTimer( globals, why );
|
||||
drop = XP_TRUE;
|
||||
}
|
||||
for ( why = 1; why < NUM_TIMERS_PLUS_ONE; ++why ) {
|
||||
TimerData* timer = &globals->timerData[why];
|
||||
if ( !!timer->proc && now >= timer->when ) {
|
||||
(void)ceFireTimer( globals, why );
|
||||
drop = XP_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2659,7 +2652,7 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
/* Kill since they otherwise repeat, but kill before firing
|
||||
as fired proc may set another. */
|
||||
(void)KillTimer( hWnd, globals->timerIDs[why] );
|
||||
(void)KillTimer( hWnd, globals->timerData[why].id );
|
||||
|
||||
draw = ceFireTimer( globals, why );
|
||||
}
|
||||
|
@ -3071,6 +3064,8 @@ ce_send_proc( const XP_U8* buf, XP_U16 len, const CommsAddrRec* addrp,
|
|||
CommsAddrRec addr;
|
||||
LOG_FUNC();
|
||||
|
||||
XP_ASSERT( !!globals->game.comms );
|
||||
|
||||
if ( !addrp ) {
|
||||
comms_getAddr( globals->game.comms, &addr );
|
||||
addrp = &addr;
|
||||
|
@ -3391,10 +3386,11 @@ ce_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
|||
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
||||
XP_U32 timerID;
|
||||
XP_U32 howLong;
|
||||
TimerData* timer = &globals->timerData[why];
|
||||
|
||||
XP_ASSERT( why < NUM_TIMERS_PLUS_ONE );
|
||||
globals->timerProcs[why] = proc;
|
||||
globals->timerClosures[why] = closure;
|
||||
timer->proc = proc;
|
||||
timer->closure = closure;
|
||||
|
||||
switch ( why ) {
|
||||
case TIMER_PENDOWN:
|
||||
|
@ -3413,13 +3409,24 @@ ce_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
|||
return;
|
||||
}
|
||||
|
||||
globals->timerWhens[why] = GetCurrentTime() + howLong;
|
||||
timer->when = GetCurrentTime() + howLong;
|
||||
|
||||
timerID = SetTimer( globals->hWnd, why, howLong, NULL);
|
||||
|
||||
globals->timerIDs[why] = timerID;
|
||||
timer->id = timerID;
|
||||
} /* ce_util_setTimer */
|
||||
|
||||
static void
|
||||
ce_util_clearTimer( XW_UtilCtxt* uc, XWTimerReason why )
|
||||
{
|
||||
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
||||
TimerData* timer = &globals->timerData[why];
|
||||
if ( !!timer->proc ) {
|
||||
timer->proc = NULL;
|
||||
KillTimer( globals->hWnd, timer->id );
|
||||
}
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
ce_util_altKeyDown( XW_UtilCtxt* XP_UNUSED(uc) )
|
||||
{
|
||||
|
|
|
@ -110,6 +110,13 @@ enum {
|
|||
N_CACHED_PATHS
|
||||
};
|
||||
|
||||
typedef struct _TimerData {
|
||||
XP_U32 id;
|
||||
XWTimerProc proc;
|
||||
void* closure;
|
||||
XP_U32 when;
|
||||
} TimerData;
|
||||
|
||||
typedef struct _CEAppGlobals {
|
||||
HINSTANCE hInst;
|
||||
HINSTANCE locInst; /* same as hInst if no l10n DLL in use */
|
||||
|
@ -139,10 +146,7 @@ typedef struct _CEAppGlobals {
|
|||
VTableMgr* vtMgr;
|
||||
XP_U16* bonusInfo;
|
||||
|
||||
XP_U32 timerIDs[NUM_TIMERS_PLUS_ONE];
|
||||
XWTimerProc timerProcs[NUM_TIMERS_PLUS_ONE];
|
||||
void* timerClosures[NUM_TIMERS_PLUS_ONE];
|
||||
XP_U32 timerWhens[NUM_TIMERS_PLUS_ONE];
|
||||
TimerData timerData[NUM_TIMERS_PLUS_ONE];
|
||||
|
||||
RECT ownedRects[N_OWNED_RECTS];
|
||||
|
||||
|
|
Loading…
Reference in a new issue